@loopstack/sandbox-filesystem 0.5.0 → 0.5.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.
- package/README.md +90 -133
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -30,11 +30,11 @@ See [SETUP.md](./SETUP.md) for installation and setup instructions.
|
|
|
30
30
|
|
|
31
31
|
## Usage
|
|
32
32
|
|
|
33
|
-
Inject the tools in your workflow class using the
|
|
33
|
+
Inject the tools in your workflow class using the `@InjectTool()` decorator:
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
36
|
import { z } from 'zod';
|
|
37
|
-
import { InjectTool,
|
|
37
|
+
import { BaseWorkflow, Final, Initial, InjectTool, ToolResult, Transition, Workflow } from '@loopstack/common';
|
|
38
38
|
import {
|
|
39
39
|
SandboxCreateDirectory,
|
|
40
40
|
SandboxDelete,
|
|
@@ -48,24 +48,11 @@ import { SandboxDestroy, SandboxInit } from '@loopstack/sandbox-tool';
|
|
|
48
48
|
|
|
49
49
|
@Workflow({
|
|
50
50
|
uiConfig: __dirname + '/my.ui.yaml',
|
|
51
|
+
schema: z.object({
|
|
52
|
+
outputDir: z.string().default(process.cwd() + '/out'),
|
|
53
|
+
}),
|
|
51
54
|
})
|
|
52
|
-
export class MyWorkflow {
|
|
53
|
-
@Input({
|
|
54
|
-
schema: z.object({
|
|
55
|
-
outputDir: z.string().default(process.cwd() + '/out'),
|
|
56
|
-
}),
|
|
57
|
-
})
|
|
58
|
-
args: { outputDir: string };
|
|
59
|
-
|
|
60
|
-
@State({
|
|
61
|
-
schema: z.object({
|
|
62
|
-
containerId: z.string().optional(),
|
|
63
|
-
fileContent: z.string().optional(),
|
|
64
|
-
fileList: z.array(z.any()).optional(),
|
|
65
|
-
}),
|
|
66
|
-
})
|
|
67
|
-
state: { containerId: string; fileContent: string; fileList: any[] };
|
|
68
|
-
|
|
55
|
+
export class MyWorkflow extends BaseWorkflow<{ outputDir: string }> {
|
|
69
56
|
// Sandbox lifecycle tools (from @loopstack/sandbox-tool)
|
|
70
57
|
@InjectTool() sandboxInit: SandboxInit;
|
|
71
58
|
@InjectTool() sandboxDestroy: SandboxDestroy;
|
|
@@ -78,119 +65,89 @@ export class MyWorkflow {
|
|
|
78
65
|
@InjectTool() sandboxDelete: SandboxDelete;
|
|
79
66
|
@InjectTool() sandboxExists: SandboxExists;
|
|
80
67
|
@InjectTool() sandboxFileInfo: SandboxFileInfo;
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
68
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
call
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
from: existence_checked
|
|
167
|
-
to: info_retrieved
|
|
168
|
-
call:
|
|
169
|
-
- tool: sandboxFileInfo
|
|
170
|
-
args:
|
|
171
|
-
containerId: ${{ state.containerId }}
|
|
172
|
-
path: /workspace/result.txt
|
|
173
|
-
|
|
174
|
-
# Delete the file
|
|
175
|
-
- id: delete_file
|
|
176
|
-
from: info_retrieved
|
|
177
|
-
to: file_deleted
|
|
178
|
-
call:
|
|
179
|
-
- tool: sandboxDelete
|
|
180
|
-
args:
|
|
181
|
-
containerId: ${{ state.containerId }}
|
|
182
|
-
path: /workspace/result.txt
|
|
183
|
-
force: true
|
|
184
|
-
|
|
185
|
-
# Destroy the sandbox container (cleanup)
|
|
186
|
-
- id: destroy_sandbox
|
|
187
|
-
from: file_deleted
|
|
188
|
-
to: end
|
|
189
|
-
call:
|
|
190
|
-
- tool: sandboxDestroy
|
|
191
|
-
args:
|
|
192
|
-
containerId: ${{ state.containerId }}
|
|
193
|
-
removeContainer: true
|
|
69
|
+
containerId?: string;
|
|
70
|
+
fileContent?: string;
|
|
71
|
+
|
|
72
|
+
// Initialize the sandbox container (required before filesystem operations)
|
|
73
|
+
@Initial({ to: 'sandbox_ready' })
|
|
74
|
+
async initSandbox(args: { outputDir: string }) {
|
|
75
|
+
const result = await this.sandboxInit.call({
|
|
76
|
+
containerId: 'my-sandbox',
|
|
77
|
+
imageName: 'node:18',
|
|
78
|
+
containerName: 'my-filesystem-sandbox',
|
|
79
|
+
projectOutPath: args.outputDir,
|
|
80
|
+
rootPath: 'workspace',
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
this.containerId = result.data!.containerId;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Create a directory and write a file
|
|
87
|
+
@Transition({ from: 'sandbox_ready', to: 'file_written' })
|
|
88
|
+
async writeFile() {
|
|
89
|
+
await this.sandboxCreateDirectory.call({
|
|
90
|
+
containerId: this.containerId!,
|
|
91
|
+
path: '/workspace/output',
|
|
92
|
+
recursive: true,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await this.sandboxWriteFile.call({
|
|
96
|
+
containerId: this.containerId!,
|
|
97
|
+
path: '/workspace/output/result.txt',
|
|
98
|
+
content: 'Hello from sandbox!',
|
|
99
|
+
encoding: 'utf8',
|
|
100
|
+
createParentDirs: true,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Read the file back
|
|
105
|
+
@Transition({ from: 'file_written', to: 'file_read' })
|
|
106
|
+
async readFile() {
|
|
107
|
+
const result = await this.sandboxReadFile.call({
|
|
108
|
+
containerId: this.containerId!,
|
|
109
|
+
path: '/workspace/output/result.txt',
|
|
110
|
+
encoding: 'utf8',
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
this.fileContent = result.data!.content;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// List directory, check existence, get info
|
|
117
|
+
@Transition({ from: 'file_read', to: 'inspected' })
|
|
118
|
+
async inspectFiles() {
|
|
119
|
+
await this.sandboxListDirectory.call({
|
|
120
|
+
containerId: this.containerId!,
|
|
121
|
+
path: '/workspace/output',
|
|
122
|
+
recursive: false,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
await this.sandboxExists.call({
|
|
126
|
+
containerId: this.containerId!,
|
|
127
|
+
path: '/workspace/output/result.txt',
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
await this.sandboxFileInfo.call({
|
|
131
|
+
containerId: this.containerId!,
|
|
132
|
+
path: '/workspace/output/result.txt',
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Clean up and destroy the sandbox
|
|
137
|
+
@Final({ from: 'inspected' })
|
|
138
|
+
async cleanup() {
|
|
139
|
+
await this.sandboxDelete.call({
|
|
140
|
+
containerId: this.containerId!,
|
|
141
|
+
path: '/workspace/output/result.txt',
|
|
142
|
+
force: true,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
await this.sandboxDestroy.call({
|
|
146
|
+
containerId: this.containerId!,
|
|
147
|
+
removeContainer: true,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
194
151
|
```
|
|
195
152
|
|
|
196
153
|
## About
|
|
@@ -201,6 +158,6 @@ License: Apache-2.0
|
|
|
201
158
|
|
|
202
159
|
### Additional Resources:
|
|
203
160
|
|
|
204
|
-
- [Loopstack Documentation](https://loopstack.ai)
|
|
205
|
-
- [Getting Started with Loopstack](https://loopstack.ai)
|
|
161
|
+
- [Loopstack Documentation](https://loopstack.ai/docs)
|
|
162
|
+
- [Getting Started with Loopstack](https://loopstack.ai/docs/getting-started)
|
|
206
163
|
- For more examples how to use this tool look for `@loopstack/sandbox-filesystem` in the [Loopstack Registry](https://loopstack.ai/registry)
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"filesystem",
|
|
8
8
|
"sandbox"
|
|
9
9
|
],
|
|
10
|
-
"version": "0.5.
|
|
10
|
+
"version": "0.5.1",
|
|
11
11
|
"license": "Apache-2.0",
|
|
12
12
|
"author": {
|
|
13
13
|
"name": "Tobias Blättermann, Jakob Klippel"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@loopstack/common": "^0.25.0",
|
|
31
|
-
"@loopstack/sandbox-tool": "^0.5.
|
|
31
|
+
"@loopstack/sandbox-tool": "^0.5.1",
|
|
32
32
|
"@nestjs/common": "^11.1.14",
|
|
33
33
|
"zod": "^4.3.6"
|
|
34
34
|
},
|