@loopstack/filesystem-examples 0.1.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.
Files changed (32) hide show
  1. package/README.md +92 -0
  2. package/dist/filesystem-examples.module.d.ts +3 -0
  3. package/dist/filesystem-examples.module.d.ts.map +1 -0
  4. package/dist/filesystem-examples.module.js +47 -0
  5. package/dist/filesystem-examples.module.js.map +1 -0
  6. package/dist/index.d.ts +6 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +22 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/workflows/local-file-explorer/local-file-explorer-example.workflow.d.ts +12 -0
  11. package/dist/workflows/local-file-explorer/local-file-explorer-example.workflow.d.ts.map +1 -0
  12. package/dist/workflows/local-file-explorer/local-file-explorer-example.workflow.js +50 -0
  13. package/dist/workflows/local-file-explorer/local-file-explorer-example.workflow.js.map +1 -0
  14. package/dist/workflows/remote-client/remote-client-example.workflow.d.ts +16 -0
  15. package/dist/workflows/remote-client/remote-client-example.workflow.d.ts.map +1 -0
  16. package/dist/workflows/remote-client/remote-client-example.workflow.js +84 -0
  17. package/dist/workflows/remote-client/remote-client-example.workflow.js.map +1 -0
  18. package/dist/workflows/remote-file-explorer/remote-file-explorer-example.workflow.d.ts +14 -0
  19. package/dist/workflows/remote-file-explorer/remote-file-explorer-example.workflow.d.ts.map +1 -0
  20. package/dist/workflows/remote-file-explorer/remote-file-explorer-example.workflow.js +72 -0
  21. package/dist/workflows/remote-file-explorer/remote-file-explorer-example.workflow.js.map +1 -0
  22. package/dist/workflows/sandbox/sandbox-example.workflow.d.ts +44 -0
  23. package/dist/workflows/sandbox/sandbox-example.workflow.d.ts.map +1 -0
  24. package/dist/workflows/sandbox/sandbox-example.workflow.js +224 -0
  25. package/dist/workflows/sandbox/sandbox-example.workflow.js.map +1 -0
  26. package/package.json +52 -0
  27. package/src/filesystem-examples.module.ts +35 -0
  28. package/src/index.ts +5 -0
  29. package/src/workflows/local-file-explorer/local-file-explorer-example.workflow.ts +34 -0
  30. package/src/workflows/remote-client/remote-client-example.workflow.ts +57 -0
  31. package/src/workflows/remote-file-explorer/remote-file-explorer-example.workflow.ts +54 -0
  32. package/src/workflows/sandbox/sandbox-example.workflow.ts +194 -0
package/README.md ADDED
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: Filesystem Examples
3
+ description: Workflow examples for filesystem operations in Loopstack — Docker sandbox, remote file browsing, remote command execution, local file tree.
4
+ ---
5
+
6
+ # @loopstack/filesystem-examples
7
+
8
+ > Filesystem workflow examples for the [Loopstack](https://loopstack.ai) automation framework.
9
+
10
+ Four ways workflows interact with the filesystem in Loopstack: isolated Docker sandboxes, remote workspace browsing, remote command execution, and local file-tree inspection.
11
+
12
+ ## Install as Source (Recommended)
13
+
14
+ ```bash
15
+ npx giget@latest gh:loopstack-ai/loopstack/registry/examples/filesystem-examples src/filesystem-examples
16
+ ```
17
+
18
+ Register the module:
19
+
20
+ ```typescript
21
+ import { Module } from '@nestjs/common';
22
+ import { LoopstackModule } from '@loopstack/loopstack-module';
23
+ import { FilesystemExamplesModule } from './filesystem-examples/filesystem-examples.module';
24
+
25
+ @Module({
26
+ imports: [LoopstackModule.forRoot(), FilesystemExamplesModule],
27
+ })
28
+ export class AppModule {}
29
+ ```
30
+
31
+ ## Install as a Dependency
32
+
33
+ ```bash
34
+ npm install @loopstack/filesystem-examples
35
+ ```
36
+
37
+ ```typescript
38
+ import { FilesystemExamplesModule } from '@loopstack/filesystem-examples';
39
+ ```
40
+
41
+ ## Environment
42
+
43
+ The sandbox example requires Docker. The remote examples require a running remote server (`SANDBOX_URL`, `SANDBOX_AGENT_URL`) — see `@loopstack/remote-client`'s `forRoot` config.
44
+
45
+ ## Examples
46
+
47
+ | Example | Studio title | Description |
48
+ | --------------------------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------- |
49
+ | [Sandbox](#sandbox) | `Filesystem - Sandbox Example` | Full Docker sandbox lifecycle — init, file ops, destroy |
50
+ | [Remote File Explorer](#remote-file-explorer) | `Filesystem - Remote File Explorer Example` | Browse a remote workspace via `GlobTool` + `ReadTool` |
51
+ | [Remote Client](#remote-client) | `Filesystem - Remote Client Example` | Run commands and edit files on a remote machine via `BashTool` + `WriteTool` |
52
+ | [Local File Explorer](#local-file-explorer) | `Filesystem - Local File Explorer Example` | Build a workspace file tree with `FileSystemService` |
53
+
54
+ ---
55
+
56
+ ## Sandbox
57
+
58
+ Walks the complete Docker sandbox lifecycle: `sandboxInit` → directory + file operations (`sandboxCreateDirectory`, `sandboxWriteFile`, `sandboxReadFile`, `sandboxListDirectory`, `sandboxExists`, `sandboxFileInfo`, `sandboxDelete`) → `sandboxDestroy`. Useful for isolated execution of untrusted code.
59
+
60
+ ### Files
61
+
62
+ - `sandbox-example.workflow.ts` — workflow class
63
+
64
+ ## Remote File Explorer
65
+
66
+ Uses `GlobTool` and `ReadTool` from `@loopstack/remote-client` to find Markdown files in a remote workspace and read the first match.
67
+
68
+ ### Files
69
+
70
+ - `remote-file-explorer-example.workflow.ts` — workflow class
71
+
72
+ ## Remote Client
73
+
74
+ Demonstrates `@loopstack/remote-client` beyond file browsing: write a file via `WriteTool`, run a shell command via `BashTool`, then read the result with `ReadTool`. Useful when you need command execution against a remote workspace.
75
+
76
+ ### Files
77
+
78
+ - `remote-client-example.workflow.ts` — workflow class
79
+
80
+ ## Local File Explorer
81
+
82
+ Demonstrates `FileSystemService` from `@loopstack/local-file-explorer-module` — builds a file tree of the workspace root and renders it as markdown. The same module also exposes a REST API for the Studio file panel.
83
+
84
+ ### Files
85
+
86
+ - `local-file-explorer-example.workflow.ts` — workflow class
87
+
88
+ ## About
89
+
90
+ Author: [Jakob Klippel](https://www.linkedin.com/in/jakob-klippel/)
91
+
92
+ License: MIT
@@ -0,0 +1,3 @@
1
+ export declare class FilesystemExamplesModule {
2
+ }
3
+ //# sourceMappingURL=filesystem-examples.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-examples.module.d.ts","sourceRoot":"","sources":["../src/filesystem-examples.module.ts"],"names":[],"mappings":"AAmBA,qBAea,wBAAwB;CAAG"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.FilesystemExamplesModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const common_2 = require("@loopstack/common");
12
+ const local_file_explorer_module_1 = require("@loopstack/local-file-explorer-module");
13
+ const remote_client_1 = require("@loopstack/remote-client");
14
+ const remote_file_explorer_module_1 = require("@loopstack/remote-file-explorer-module");
15
+ const sandbox_filesystem_1 = require("@loopstack/sandbox-filesystem");
16
+ const sandbox_tool_1 = require("@loopstack/sandbox-tool");
17
+ const local_file_explorer_example_workflow_1 = require("./workflows/local-file-explorer/local-file-explorer-example.workflow");
18
+ const remote_client_example_workflow_1 = require("./workflows/remote-client/remote-client-example.workflow");
19
+ const remote_file_explorer_example_workflow_1 = require("./workflows/remote-file-explorer/remote-file-explorer-example.workflow");
20
+ const sandbox_example_workflow_1 = require("./workflows/sandbox/sandbox-example.workflow");
21
+ const WORKFLOWS = [
22
+ sandbox_example_workflow_1.SandboxExampleWorkflow,
23
+ remote_file_explorer_example_workflow_1.RemoteFileExplorerExampleWorkflow,
24
+ remote_client_example_workflow_1.RemoteClientExampleWorkflow,
25
+ local_file_explorer_example_workflow_1.LocalFileExplorerExampleWorkflow,
26
+ ];
27
+ let FilesystemExamplesModule = class FilesystemExamplesModule {
28
+ };
29
+ exports.FilesystemExamplesModule = FilesystemExamplesModule;
30
+ exports.FilesystemExamplesModule = FilesystemExamplesModule = __decorate([
31
+ (0, common_2.StudioApp)({
32
+ title: 'Filesystem Examples',
33
+ workflows: WORKFLOWS,
34
+ }),
35
+ (0, common_1.Module)({
36
+ imports: [
37
+ sandbox_filesystem_1.SandboxFilesystemModule,
38
+ sandbox_tool_1.SandboxToolModule,
39
+ remote_file_explorer_module_1.RemoteFileExplorerModule.forFeature(),
40
+ remote_client_1.RemoteClientModule.forFeature({ slots: [{ id: 'sandbox', type: 'sandbox', title: 'Sandbox' }] }),
41
+ local_file_explorer_module_1.LocalFileExplorerModule.forFeature(),
42
+ ],
43
+ providers: WORKFLOWS,
44
+ exports: WORKFLOWS,
45
+ })
46
+ ], FilesystemExamplesModule);
47
+ //# sourceMappingURL=filesystem-examples.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-examples.module.js","sourceRoot":"","sources":["../src/filesystem-examples.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,8CAA8C;AAC9C,sFAAgF;AAChF,4DAA8D;AAC9D,wFAAkF;AAClF,sEAAwE;AACxE,0DAA4D;AAC5D,+HAAwH;AACxH,6GAAuG;AACvG,kIAA2H;AAC3H,2FAAsF;AAEtF,MAAM,SAAS,GAAG;IAChB,iDAAsB;IACtB,yEAAiC;IACjC,4DAA2B;IAC3B,uEAAgC;CACjC,CAAC;AAiBK,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;CAAG,CAAA;AAA3B,4DAAwB;mCAAxB,wBAAwB;IAfpC,IAAA,kBAAS,EAAC;QACT,KAAK,EAAE,qBAAqB;QAC5B,SAAS,EAAE,SAAS;KACrB,CAAC;IACD,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,4CAAuB;YACvB,gCAAiB;YACjB,sDAAwB,CAAC,UAAU,EAAE;YACrC,kCAAkB,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;YAChG,oDAAuB,CAAC,UAAU,EAAE;SACrC;QACD,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,SAAS;KACnB,CAAC;GACW,wBAAwB,CAAG"}
@@ -0,0 +1,6 @@
1
+ export * from './filesystem-examples.module';
2
+ export * from './workflows/sandbox/sandbox-example.workflow';
3
+ export * from './workflows/remote-file-explorer/remote-file-explorer-example.workflow';
4
+ export * from './workflows/remote-client/remote-client-example.workflow';
5
+ export * from './workflows/local-file-explorer/local-file-explorer-example.workflow';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8CAA8C,CAAC;AAC7D,cAAc,wEAAwE,CAAC;AACvF,cAAc,0DAA0D,CAAC;AACzE,cAAc,sEAAsE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./filesystem-examples.module"), exports);
18
+ __exportStar(require("./workflows/sandbox/sandbox-example.workflow"), exports);
19
+ __exportStar(require("./workflows/remote-file-explorer/remote-file-explorer-example.workflow"), exports);
20
+ __exportStar(require("./workflows/remote-client/remote-client-example.workflow"), exports);
21
+ __exportStar(require("./workflows/local-file-explorer/local-file-explorer-example.workflow"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+DAA6C;AAC7C,+EAA6D;AAC7D,yGAAuF;AACvF,2FAAyE;AACzE,uGAAqF"}
@@ -0,0 +1,12 @@
1
+ import { BaseWorkflow } from '@loopstack/common';
2
+ import { FileSystemService } from '@loopstack/local-file-explorer-module';
3
+ interface LocalFileExplorerState {
4
+ fileCount?: number;
5
+ }
6
+ export declare class LocalFileExplorerExampleWorkflow extends BaseWorkflow {
7
+ private readonly fileSystem;
8
+ constructor(fileSystem: FileSystemService);
9
+ listTree(_state: LocalFileExplorerState): Promise<void>;
10
+ }
11
+ export {};
12
+ //# sourceMappingURL=local-file-explorer-example.workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-file-explorer-example.workflow.d.ts","sourceRoot":"","sources":["../../../src/workflows/local-file-explorer/local-file-explorer-example.workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA0C,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE1E,UAAU,sBAAsB;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAKa,gCAAiC,SAAQ,YAAY;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,iBAAiB;IAKpD,QAAQ,CAAC,MAAM,EAAE,sBAAsB;CAe9C"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.LocalFileExplorerExampleWorkflow = void 0;
13
+ const common_1 = require("@loopstack/common");
14
+ const local_file_explorer_module_1 = require("@loopstack/local-file-explorer-module");
15
+ let LocalFileExplorerExampleWorkflow = class LocalFileExplorerExampleWorkflow extends common_1.BaseWorkflow {
16
+ fileSystem;
17
+ constructor(fileSystem) {
18
+ super();
19
+ this.fileSystem = fileSystem;
20
+ }
21
+ async listTree(_state) {
22
+ const tree = await this.fileSystem.buildFileTree(process.cwd());
23
+ const lines = tree.slice(0, 50).map((node) => `- ${node.path} (${node.type})`);
24
+ await this.documentStore.save(common_1.MarkdownDocument, {
25
+ markdown: [
26
+ `# Workspace File Tree`,
27
+ '',
28
+ `Found ${tree.length} top-level entries in \`${process.cwd()}\`.`,
29
+ '',
30
+ ...lines,
31
+ tree.length > 50 ? `\n_(${tree.length - 50} more entries omitted)_` : '',
32
+ ].join('\n'),
33
+ });
34
+ }
35
+ };
36
+ exports.LocalFileExplorerExampleWorkflow = LocalFileExplorerExampleWorkflow;
37
+ __decorate([
38
+ (0, common_1.Transition)({ to: 'end' }),
39
+ __metadata("design:type", Function),
40
+ __metadata("design:paramtypes", [Object]),
41
+ __metadata("design:returntype", Promise)
42
+ ], LocalFileExplorerExampleWorkflow.prototype, "listTree", null);
43
+ exports.LocalFileExplorerExampleWorkflow = LocalFileExplorerExampleWorkflow = __decorate([
44
+ (0, common_1.Workflow)({
45
+ title: 'Filesystem - Local File Explorer Example',
46
+ description: 'Demonstrates @loopstack/local-file-explorer-module — uses FileSystemService to build a file tree of the workspace root and render it as markdown. The module also exposes a REST API for the Studio file panel.',
47
+ }),
48
+ __metadata("design:paramtypes", [local_file_explorer_module_1.FileSystemService])
49
+ ], LocalFileExplorerExampleWorkflow);
50
+ //# sourceMappingURL=local-file-explorer-example.workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-file-explorer-example.workflow.js","sourceRoot":"","sources":["../../../src/workflows/local-file-explorer/local-file-explorer-example.workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAAyF;AACzF,sFAA0E;AAWnE,IAAM,gCAAgC,GAAtC,MAAM,gCAAiC,SAAQ,qBAAY;IACnC;IAA7B,YAA6B,UAA6B;QACxD,KAAK,EAAE,CAAC;QADmB,eAAU,GAAV,UAAU,CAAmB;IAE1D,CAAC;IAGK,AAAN,KAAK,CAAC,QAAQ,CAAC,MAA8B;QAC3C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAE/E,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,yBAAgB,EAAE;YAC9C,QAAQ,EAAE;gBACR,uBAAuB;gBACvB,EAAE;gBACF,SAAS,IAAI,CAAC,MAAM,2BAA2B,OAAO,CAAC,GAAG,EAAE,KAAK;gBACjE,EAAE;gBACF,GAAG,KAAK;gBACR,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,yBAAyB,CAAC,CAAC,CAAC,EAAE;aACzE,CAAC,IAAI,CAAC,IAAI,CAAC;SACb,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AArBY,4EAAgC;AAMrC;IADL,IAAA,mBAAU,EAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;;;;gEAezB;2CApBU,gCAAgC;IAL5C,IAAA,iBAAQ,EAAC;QACR,KAAK,EAAE,0CAA0C;QACjD,WAAW,EACT,iNAAiN;KACpN,CAAC;qCAEyC,8CAAiB;GAD/C,gCAAgC,CAqB5C"}
@@ -0,0 +1,16 @@
1
+ import { BaseWorkflow } from '@loopstack/common';
2
+ import { BashTool, ReadTool, WriteTool } from '@loopstack/remote-client';
3
+ interface RemoteClientState {
4
+ filePath?: string;
5
+ }
6
+ export declare class RemoteClientExampleWorkflow extends BaseWorkflow {
7
+ private readonly bash;
8
+ private readonly read;
9
+ private readonly write;
10
+ constructor(bash: BashTool, read: ReadTool, write: WriteTool);
11
+ writeFile(_state: RemoteClientState): Promise<void>;
12
+ runCommand(state: RemoteClientState): Promise<void>;
13
+ readBack(state: RemoteClientState): Promise<void>;
14
+ }
15
+ export {};
16
+ //# sourceMappingURL=remote-client-example.workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-client-example.workflow.d.ts","sourceRoot":"","sources":["../../../src/workflows/remote-client/remote-client-example.workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAyC,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAEzE,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAKa,2BAA4B,SAAQ,YAAY;IAEzD,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAFL,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,SAAS;IAM7B,SAAS,CAAC,MAAM,EAAE,iBAAiB;IAcnC,UAAU,CAAC,KAAK,EAAE,iBAAiB;IAYnC,QAAQ,CAAC,KAAK,EAAE,iBAAiB;CAQxC"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RemoteClientExampleWorkflow = void 0;
13
+ const common_1 = require("@loopstack/common");
14
+ const remote_client_1 = require("@loopstack/remote-client");
15
+ let RemoteClientExampleWorkflow = class RemoteClientExampleWorkflow extends common_1.BaseWorkflow {
16
+ bash;
17
+ read;
18
+ write;
19
+ constructor(bash, read, write) {
20
+ super();
21
+ this.bash = bash;
22
+ this.read = read;
23
+ this.write = write;
24
+ }
25
+ async writeFile(_state) {
26
+ const filePath = '/tmp/remote-client-example.txt';
27
+ await this.write.call({
28
+ file_path: filePath,
29
+ content: 'Hello from RemoteClientExampleWorkflow!\n',
30
+ });
31
+ await this.documentStore.save(common_1.MessageDocument, {
32
+ role: 'assistant',
33
+ text: `Wrote file ${filePath}.`,
34
+ });
35
+ this.assignState({ filePath });
36
+ }
37
+ async runCommand(state) {
38
+ const result = await this.bash.call({
39
+ command: `wc -l ${state.filePath} && date`,
40
+ });
41
+ const stdout = result.data?.stdout ?? '';
42
+ await this.documentStore.save(common_1.MessageDocument, {
43
+ role: 'assistant',
44
+ text: `Command output:\n\`\`\`\n${stdout}\n\`\`\``,
45
+ });
46
+ }
47
+ async readBack(state) {
48
+ const result = await this.read.call({ file_path: state.filePath });
49
+ const content = result.data?.content ?? '';
50
+ await this.documentStore.save(common_1.MessageDocument, {
51
+ role: 'assistant',
52
+ text: `Final file content:\n\`\`\`\n${content}\n\`\`\``,
53
+ });
54
+ }
55
+ };
56
+ exports.RemoteClientExampleWorkflow = RemoteClientExampleWorkflow;
57
+ __decorate([
58
+ (0, common_1.Transition)({ to: 'file_written' }),
59
+ __metadata("design:type", Function),
60
+ __metadata("design:paramtypes", [Object]),
61
+ __metadata("design:returntype", Promise)
62
+ ], RemoteClientExampleWorkflow.prototype, "writeFile", null);
63
+ __decorate([
64
+ (0, common_1.Transition)({ from: 'file_written', to: 'command_executed' }),
65
+ __metadata("design:type", Function),
66
+ __metadata("design:paramtypes", [Object]),
67
+ __metadata("design:returntype", Promise)
68
+ ], RemoteClientExampleWorkflow.prototype, "runCommand", null);
69
+ __decorate([
70
+ (0, common_1.Transition)({ from: 'command_executed', to: 'end' }),
71
+ __metadata("design:type", Function),
72
+ __metadata("design:paramtypes", [Object]),
73
+ __metadata("design:returntype", Promise)
74
+ ], RemoteClientExampleWorkflow.prototype, "readBack", null);
75
+ exports.RemoteClientExampleWorkflow = RemoteClientExampleWorkflow = __decorate([
76
+ (0, common_1.Workflow)({
77
+ title: 'Filesystem - Remote Client Example',
78
+ description: 'Demonstrates @loopstack/remote-client tools beyond file browsing: write a file, run a shell command on the remote machine via BashTool, read the result. Useful when you need command execution against a remote workspace.',
79
+ }),
80
+ __metadata("design:paramtypes", [remote_client_1.BashTool,
81
+ remote_client_1.ReadTool,
82
+ remote_client_1.WriteTool])
83
+ ], RemoteClientExampleWorkflow);
84
+ //# sourceMappingURL=remote-client-example.workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-client-example.workflow.js","sourceRoot":"","sources":["../../../src/workflows/remote-client/remote-client-example.workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAAwF;AACxF,4DAAyE;AAWlE,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,qBAAY;IAExC;IACA;IACA;IAHnB,YACmB,IAAc,EACd,IAAc,EACd,KAAgB;QAEjC,KAAK,EAAE,CAAC;QAJS,SAAI,GAAJ,IAAI,CAAU;QACd,SAAI,GAAJ,IAAI,CAAU;QACd,UAAK,GAAL,KAAK,CAAW;IAGnC,CAAC;IAGK,AAAN,KAAK,CAAC,SAAS,CAAC,MAAyB;QACvC,MAAM,QAAQ,GAAG,gCAAgC,CAAC;QAClD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACpB,SAAS,EAAE,QAAQ;YACnB,OAAO,EAAE,2CAA2C;SACrD,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,wBAAe,EAAE;YAC7C,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,cAAc,QAAQ,GAAG;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACjC,CAAC;IAGK,AAAN,KAAK,CAAC,UAAU,CAAC,KAAwB;QACvC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAClC,OAAO,EAAE,SAAS,KAAK,CAAC,QAAQ,UAAU;SAC3C,CAAC,CAAC;QACH,MAAM,MAAM,GAAI,MAAM,CAAC,IAA4B,EAAE,MAAM,IAAI,EAAE,CAAC;QAClE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,wBAAe,EAAE;YAC7C,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,4BAA4B,MAAM,UAAU;SACnD,CAAC,CAAC;IACL,CAAC;IAGK,AAAN,KAAK,CAAC,QAAQ,CAAC,KAAwB;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,QAAS,EAAE,CAAC,CAAC;QACpE,MAAM,OAAO,GAAI,MAAM,CAAC,IAA6B,EAAE,OAAO,IAAI,EAAE,CAAC;QACrE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,wBAAe,EAAE;YAC7C,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,gCAAgC,OAAO,UAAU;SACxD,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AA5CY,kEAA2B;AAUhC;IADL,IAAA,mBAAU,EAAC,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC;;;;4DAYlC;AAGK;IADL,IAAA,mBAAU,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,kBAAkB,EAAE,CAAC;;;;6DAU5D;AAGK;IADL,IAAA,mBAAU,EAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;;;;2DAQnD;sCA3CU,2BAA2B;IALvC,IAAA,iBAAQ,EAAC;QACR,KAAK,EAAE,oCAAoC;QAC3C,WAAW,EACT,6NAA6N;KAChO,CAAC;qCAGyB,wBAAQ;QACR,wBAAQ;QACP,yBAAS;GAJxB,2BAA2B,CA4CvC"}
@@ -0,0 +1,14 @@
1
+ import { BaseWorkflow } from '@loopstack/common';
2
+ import { GlobTool, ReadTool } from '@loopstack/remote-client';
3
+ interface RemoteFileExplorerState {
4
+ firstMatch?: string;
5
+ }
6
+ export declare class RemoteFileExplorerExampleWorkflow extends BaseWorkflow {
7
+ private readonly glob;
8
+ private readonly read;
9
+ constructor(glob: GlobTool, read: ReadTool);
10
+ listFiles(_state: RemoteFileExplorerState): Promise<void>;
11
+ readFirst(state: RemoteFileExplorerState): Promise<void>;
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=remote-file-explorer-example.workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-file-explorer-example.workflow.d.ts","sourceRoot":"","sources":["../../../src/workflows/remote-file-explorer/remote-file-explorer-example.workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAyC,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAE9D,UAAU,uBAAuB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAKa,iCAAkC,SAAQ,YAAY;IAE/D,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBADJ,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,QAAQ;IAM3B,SAAS,CAAC,MAAM,EAAE,uBAAuB;IAezC,SAAS,CAAC,KAAK,EAAE,uBAAuB;CAiB/C"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RemoteFileExplorerExampleWorkflow = void 0;
13
+ const common_1 = require("@loopstack/common");
14
+ const remote_client_1 = require("@loopstack/remote-client");
15
+ let RemoteFileExplorerExampleWorkflow = class RemoteFileExplorerExampleWorkflow extends common_1.BaseWorkflow {
16
+ glob;
17
+ read;
18
+ constructor(glob, read) {
19
+ super();
20
+ this.glob = glob;
21
+ this.read = read;
22
+ }
23
+ async listFiles(_state) {
24
+ const result = await this.glob.call({ pattern: '**/*.md' });
25
+ const files = result.data?.files ?? [];
26
+ await this.documentStore.save(common_1.MessageDocument, {
27
+ role: 'assistant',
28
+ text: `Found ${files.length} markdown files:\n${files
29
+ .slice(0, 20)
30
+ .map((f) => `- ${f}`)
31
+ .join('\n')}`,
32
+ });
33
+ this.assignState({ firstMatch: files[0] });
34
+ }
35
+ async readFirst(state) {
36
+ if (!state.firstMatch) {
37
+ await this.documentStore.save(common_1.MessageDocument, {
38
+ role: 'assistant',
39
+ text: 'No markdown files to read.',
40
+ });
41
+ return;
42
+ }
43
+ const result = await this.read.call({ file_path: state.firstMatch });
44
+ const content = result.data?.content ?? '';
45
+ await this.documentStore.save(common_1.MessageDocument, {
46
+ role: 'assistant',
47
+ text: `# ${state.firstMatch}\n\n${content.slice(0, 500)}`,
48
+ });
49
+ }
50
+ };
51
+ exports.RemoteFileExplorerExampleWorkflow = RemoteFileExplorerExampleWorkflow;
52
+ __decorate([
53
+ (0, common_1.Transition)({ to: 'listed' }),
54
+ __metadata("design:type", Function),
55
+ __metadata("design:paramtypes", [Object]),
56
+ __metadata("design:returntype", Promise)
57
+ ], RemoteFileExplorerExampleWorkflow.prototype, "listFiles", null);
58
+ __decorate([
59
+ (0, common_1.Transition)({ from: 'listed', to: 'end' }),
60
+ __metadata("design:type", Function),
61
+ __metadata("design:paramtypes", [Object]),
62
+ __metadata("design:returntype", Promise)
63
+ ], RemoteFileExplorerExampleWorkflow.prototype, "readFirst", null);
64
+ exports.RemoteFileExplorerExampleWorkflow = RemoteFileExplorerExampleWorkflow = __decorate([
65
+ (0, common_1.Workflow)({
66
+ title: 'Filesystem - Remote File Explorer Example',
67
+ description: 'Browses a remote workspace via @loopstack/remote-client GlobTool + ReadTool — finds Markdown files, reads the first match.',
68
+ }),
69
+ __metadata("design:paramtypes", [remote_client_1.GlobTool,
70
+ remote_client_1.ReadTool])
71
+ ], RemoteFileExplorerExampleWorkflow);
72
+ //# sourceMappingURL=remote-file-explorer-example.workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-file-explorer-example.workflow.js","sourceRoot":"","sources":["../../../src/workflows/remote-file-explorer/remote-file-explorer-example.workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAAwF;AACxF,4DAA8D;AAWvD,IAAM,iCAAiC,GAAvC,MAAM,iCAAkC,SAAQ,qBAAY;IAE9C;IACA;IAFnB,YACmB,IAAc,EACd,IAAc;QAE/B,KAAK,EAAE,CAAC;QAHS,SAAI,GAAJ,IAAI,CAAU;QACd,SAAI,GAAJ,IAAI,CAAU;IAGjC,CAAC;IAGK,AAAN,KAAK,CAAC,SAAS,CAAC,MAA+B;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAI,MAAM,CAAC,IAA6B,EAAE,KAAK,IAAI,EAAE,CAAC;QAEjE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,wBAAe,EAAE;YAC7C,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,SAAS,KAAK,CAAC,MAAM,qBAAqB,KAAK;iBAClD,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;iBACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;iBACpB,IAAI,CAAC,IAAI,CAAC,EAAE;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IAGK,AAAN,KAAK,CAAC,SAAS,CAAC,KAA8B;QAC5C,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,wBAAe,EAAE;gBAC7C,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,4BAA4B;aACnC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE,MAAM,OAAO,GAAI,MAAM,CAAC,IAA6B,EAAE,OAAO,IAAI,EAAE,CAAC;QAErE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,wBAAe,EAAE;YAC7C,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,KAAK,KAAK,CAAC,UAAU,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;SAC1D,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AAzCY,8EAAiC;AAStC;IADL,IAAA,mBAAU,EAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;;;;kEAa5B;AAGK;IADL,IAAA,mBAAU,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;;;;kEAiBzC;4CAxCU,iCAAiC;IAL7C,IAAA,iBAAQ,EAAC;QACR,KAAK,EAAE,2CAA2C;QAClD,WAAW,EACT,4HAA4H;KAC/H,CAAC;qCAGyB,wBAAQ;QACR,wBAAQ;GAHtB,iCAAiC,CAyC7C"}
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+ import { BaseWorkflow } from '@loopstack/common';
3
+ import type { RunContext } from '@loopstack/common';
4
+ import { SandboxCreateDirectory, SandboxDelete, SandboxExists, SandboxFileInfo, SandboxListDirectory, SandboxReadFile, SandboxWriteFile } from '@loopstack/sandbox-filesystem';
5
+ import { SandboxDestroy, SandboxInit } from '@loopstack/sandbox-tool';
6
+ interface FileEntry {
7
+ name: string;
8
+ type: string;
9
+ size: number;
10
+ path: string;
11
+ }
12
+ interface SandboxExampleState {
13
+ containerId?: string;
14
+ fileContent?: string;
15
+ fileList?: FileEntry[];
16
+ }
17
+ declare const SandboxExampleArgsSchema: z.ZodObject<{
18
+ outputDir: z.ZodDefault<z.ZodString>;
19
+ }, z.core.$strip>;
20
+ type SandboxExampleArgs = z.infer<typeof SandboxExampleArgsSchema>;
21
+ export declare class SandboxExampleWorkflow extends BaseWorkflow<SandboxExampleArgs> {
22
+ private readonly sandboxInit;
23
+ private readonly sandboxDestroy;
24
+ private readonly sandboxWriteFile;
25
+ private readonly sandboxReadFile;
26
+ private readonly sandboxListDirectory;
27
+ private readonly sandboxCreateDirectory;
28
+ private readonly sandboxDelete;
29
+ private readonly sandboxExists;
30
+ private readonly sandboxFileInfo;
31
+ constructor(sandboxInit: SandboxInit, sandboxDestroy: SandboxDestroy, sandboxWriteFile: SandboxWriteFile, sandboxReadFile: SandboxReadFile, sandboxListDirectory: SandboxListDirectory, sandboxCreateDirectory: SandboxCreateDirectory, sandboxDelete: SandboxDelete, sandboxExists: SandboxExists, sandboxFileInfo: SandboxFileInfo);
32
+ initSandbox(state: SandboxExampleState, ctx: RunContext<SandboxExampleArgs>): Promise<void>;
33
+ createDir(state: SandboxExampleState): Promise<void>;
34
+ writeFile(state: SandboxExampleState): Promise<void>;
35
+ readFile(state: SandboxExampleState): Promise<void>;
36
+ listDir(state: SandboxExampleState): Promise<void>;
37
+ checkExists(state: SandboxExampleState): Promise<void>;
38
+ getInfo(state: SandboxExampleState): Promise<void>;
39
+ deleteFile(state: SandboxExampleState): Promise<void>;
40
+ destroySandbox(state: SandboxExampleState): Promise<void>;
41
+ private formatEntries;
42
+ }
43
+ export {};
44
+ //# sourceMappingURL=sandbox-example.workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-example.workflow.d.ts","sourceRoot":"","sources":["../../../src/workflows/sandbox/sandbox-example.workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAyC,MAAM,mBAAmB,CAAC;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtE,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAmB;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;CACxB;AAED,QAAA,MAAM,wBAAwB;;iBAE5B,CAAC;AAEH,KAAK,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEnE,qBAMa,sBAAuB,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAGxE,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IACrC,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBATf,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,cAAc,EAE9B,gBAAgB,EAAE,gBAAgB,EAClC,eAAe,EAAE,eAAe,EAChC,oBAAoB,EAAE,oBAAoB,EAC1C,sBAAsB,EAAE,sBAAsB,EAC9C,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe;IAM7C,WAAW,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,EAAE,UAAU,CAAC,kBAAkB,CAAC;IAiB3E,SAAS,CAAC,KAAK,EAAE,mBAAmB;IAcpC,SAAS,CAAC,KAAK,EAAE,mBAAmB;IAgBpC,QAAQ,CAAC,KAAK,EAAE,mBAAmB;IAenC,OAAO,CAAC,KAAK,EAAE,mBAAmB;IAelC,WAAW,CAAC,KAAK,EAAE,mBAAmB;IAatC,OAAO,CAAC,KAAK,EAAE,mBAAmB;IAalC,UAAU,CAAC,KAAK,EAAE,mBAAmB;IAerC,cAAc,CAAC,KAAK,EAAE,mBAAmB;IAY/C,OAAO,CAAC,aAAa;CAMtB"}
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SandboxExampleWorkflow = void 0;
13
+ const zod_1 = require("zod");
14
+ const common_1 = require("@loopstack/common");
15
+ const sandbox_filesystem_1 = require("@loopstack/sandbox-filesystem");
16
+ const sandbox_tool_1 = require("@loopstack/sandbox-tool");
17
+ const SandboxExampleArgsSchema = zod_1.z.object({
18
+ outputDir: zod_1.z.string().default(process.cwd() + '/out'),
19
+ });
20
+ let SandboxExampleWorkflow = class SandboxExampleWorkflow extends common_1.BaseWorkflow {
21
+ sandboxInit;
22
+ sandboxDestroy;
23
+ sandboxWriteFile;
24
+ sandboxReadFile;
25
+ sandboxListDirectory;
26
+ sandboxCreateDirectory;
27
+ sandboxDelete;
28
+ sandboxExists;
29
+ sandboxFileInfo;
30
+ constructor(sandboxInit, sandboxDestroy, sandboxWriteFile, sandboxReadFile, sandboxListDirectory, sandboxCreateDirectory, sandboxDelete, sandboxExists, sandboxFileInfo) {
31
+ super();
32
+ this.sandboxInit = sandboxInit;
33
+ this.sandboxDestroy = sandboxDestroy;
34
+ this.sandboxWriteFile = sandboxWriteFile;
35
+ this.sandboxReadFile = sandboxReadFile;
36
+ this.sandboxListDirectory = sandboxListDirectory;
37
+ this.sandboxCreateDirectory = sandboxCreateDirectory;
38
+ this.sandboxDelete = sandboxDelete;
39
+ this.sandboxExists = sandboxExists;
40
+ this.sandboxFileInfo = sandboxFileInfo;
41
+ }
42
+ async initSandbox(state, ctx) {
43
+ const initResult = await this.sandboxInit.call({
44
+ containerId: 'my-sandbox',
45
+ imageName: 'node:18',
46
+ containerName: 'my-filesystem-sandbox',
47
+ projectOutPath: ctx.args.outputDir,
48
+ rootPath: 'workspace',
49
+ });
50
+ await this.documentStore.save(common_1.MessageDocument, {
51
+ role: 'assistant',
52
+ text: `Sandbox initialized successfully. Container ID: ${initResult.data.containerId}, Docker ID: ${initResult.data.dockerId}`,
53
+ });
54
+ this.assignState({ containerId: initResult.data.containerId });
55
+ }
56
+ async createDir(state) {
57
+ const mkdirResult = await this.sandboxCreateDirectory.call({
58
+ containerId: state.containerId,
59
+ path: '/workspace',
60
+ recursive: true,
61
+ });
62
+ await this.documentStore.save(common_1.MessageDocument, {
63
+ role: 'assistant',
64
+ text: `Directory created: ${mkdirResult.data.path} (created: ${mkdirResult.data.created})`,
65
+ });
66
+ }
67
+ async writeFile(state) {
68
+ const writeResult = await this.sandboxWriteFile.call({
69
+ containerId: state.containerId,
70
+ path: '/workspace/result.txt',
71
+ content: 'Hello from sandbox!',
72
+ encoding: 'utf8',
73
+ createParentDirs: true,
74
+ });
75
+ await this.documentStore.save(common_1.MessageDocument, {
76
+ role: 'assistant',
77
+ text: `File written: ${writeResult.data.path} (${writeResult.data.bytesWritten} bytes)`,
78
+ });
79
+ }
80
+ async readFile(state) {
81
+ const readResult = await this.sandboxReadFile.call({
82
+ containerId: state.containerId,
83
+ path: '/workspace/result.txt',
84
+ encoding: 'utf8',
85
+ });
86
+ await this.documentStore.save(common_1.MessageDocument, {
87
+ role: 'assistant',
88
+ text: `File read successfully. Content: "${readResult.data.content}" (encoding: ${readResult.data.encoding})`,
89
+ });
90
+ this.assignState({ fileContent: readResult.data.content });
91
+ }
92
+ async listDir(state) {
93
+ const listResult = await this.sandboxListDirectory.call({
94
+ containerId: state.containerId,
95
+ path: '/workspace',
96
+ recursive: false,
97
+ });
98
+ await this.documentStore.save(common_1.MessageDocument, {
99
+ role: 'assistant',
100
+ text: `Directory listing for ${listResult.data.path}: ${this.formatEntries(listResult.data.entries)}`,
101
+ });
102
+ this.assignState({ fileList: listResult.data.entries });
103
+ }
104
+ async checkExists(state) {
105
+ const existsResult = await this.sandboxExists.call({
106
+ containerId: state.containerId,
107
+ path: '/workspace/result.txt',
108
+ });
109
+ await this.documentStore.save(common_1.MessageDocument, {
110
+ role: 'assistant',
111
+ text: `File existence check: ${existsResult.data.path} exists=${existsResult.data.exists}, type=${existsResult.data.type}`,
112
+ });
113
+ }
114
+ async getInfo(state) {
115
+ const infoResult = await this.sandboxFileInfo.call({
116
+ containerId: state.containerId,
117
+ path: '/workspace/result.txt',
118
+ });
119
+ await this.documentStore.save(common_1.MessageDocument, {
120
+ role: 'assistant',
121
+ text: `File info for ${infoResult.data.name}: type=${infoResult.data.type}, size=${infoResult.data.size} bytes, permissions=${infoResult.data.permissions}, owner=${infoResult.data.owner}`,
122
+ });
123
+ }
124
+ async deleteFile(state) {
125
+ const deleteResult = await this.sandboxDelete.call({
126
+ containerId: state.containerId,
127
+ path: '/workspace/result.txt',
128
+ recursive: false,
129
+ force: true,
130
+ });
131
+ await this.documentStore.save(common_1.MessageDocument, {
132
+ role: 'assistant',
133
+ text: `File deleted: ${deleteResult.data.path} (deleted: ${deleteResult.data.deleted})`,
134
+ });
135
+ }
136
+ async destroySandbox(state) {
137
+ const destroyResult = await this.sandboxDestroy.call({
138
+ containerId: state.containerId,
139
+ removeContainer: true,
140
+ });
141
+ await this.documentStore.save(common_1.MessageDocument, {
142
+ role: 'assistant',
143
+ text: `Sandbox destroyed. Container ${destroyResult.data.containerId} removed=${destroyResult.data.removed}`,
144
+ });
145
+ }
146
+ formatEntries(entries) {
147
+ if (!entries || entries.length === 0) {
148
+ return '(empty)';
149
+ }
150
+ return entries.map((e) => `${e.name} (${e.type}, ${e.size} bytes)`).join(', ');
151
+ }
152
+ };
153
+ exports.SandboxExampleWorkflow = SandboxExampleWorkflow;
154
+ __decorate([
155
+ (0, common_1.Transition)({ to: 'sandbox_ready' }),
156
+ __metadata("design:type", Function),
157
+ __metadata("design:paramtypes", [Object, Object]),
158
+ __metadata("design:returntype", Promise)
159
+ ], SandboxExampleWorkflow.prototype, "initSandbox", null);
160
+ __decorate([
161
+ (0, common_1.Transition)({ from: 'sandbox_ready', to: 'dir_created' }),
162
+ __metadata("design:type", Function),
163
+ __metadata("design:paramtypes", [Object]),
164
+ __metadata("design:returntype", Promise)
165
+ ], SandboxExampleWorkflow.prototype, "createDir", null);
166
+ __decorate([
167
+ (0, common_1.Transition)({ from: 'dir_created', to: 'file_written' }),
168
+ __metadata("design:type", Function),
169
+ __metadata("design:paramtypes", [Object]),
170
+ __metadata("design:returntype", Promise)
171
+ ], SandboxExampleWorkflow.prototype, "writeFile", null);
172
+ __decorate([
173
+ (0, common_1.Transition)({ from: 'file_written', to: 'file_read' }),
174
+ __metadata("design:type", Function),
175
+ __metadata("design:paramtypes", [Object]),
176
+ __metadata("design:returntype", Promise)
177
+ ], SandboxExampleWorkflow.prototype, "readFile", null);
178
+ __decorate([
179
+ (0, common_1.Transition)({ from: 'file_read', to: 'dir_listed' }),
180
+ __metadata("design:type", Function),
181
+ __metadata("design:paramtypes", [Object]),
182
+ __metadata("design:returntype", Promise)
183
+ ], SandboxExampleWorkflow.prototype, "listDir", null);
184
+ __decorate([
185
+ (0, common_1.Transition)({ from: 'dir_listed', to: 'existence_checked' }),
186
+ __metadata("design:type", Function),
187
+ __metadata("design:paramtypes", [Object]),
188
+ __metadata("design:returntype", Promise)
189
+ ], SandboxExampleWorkflow.prototype, "checkExists", null);
190
+ __decorate([
191
+ (0, common_1.Transition)({ from: 'existence_checked', to: 'info_retrieved' }),
192
+ __metadata("design:type", Function),
193
+ __metadata("design:paramtypes", [Object]),
194
+ __metadata("design:returntype", Promise)
195
+ ], SandboxExampleWorkflow.prototype, "getInfo", null);
196
+ __decorate([
197
+ (0, common_1.Transition)({ from: 'info_retrieved', to: 'file_deleted' }),
198
+ __metadata("design:type", Function),
199
+ __metadata("design:paramtypes", [Object]),
200
+ __metadata("design:returntype", Promise)
201
+ ], SandboxExampleWorkflow.prototype, "deleteFile", null);
202
+ __decorate([
203
+ (0, common_1.Transition)({ from: 'file_deleted', to: 'end' }),
204
+ __metadata("design:type", Function),
205
+ __metadata("design:paramtypes", [Object]),
206
+ __metadata("design:returntype", Promise)
207
+ ], SandboxExampleWorkflow.prototype, "destroySandbox", null);
208
+ exports.SandboxExampleWorkflow = SandboxExampleWorkflow = __decorate([
209
+ (0, common_1.Workflow)({
210
+ title: 'Filesystem - Sandbox Example',
211
+ description: 'Demonstrates the full Docker sandbox lifecycle: init a container, perform file operations (write, read, list, delete), and destroy the sandbox. Useful for isolated execution of untrusted code.',
212
+ schema: SandboxExampleArgsSchema,
213
+ }),
214
+ __metadata("design:paramtypes", [sandbox_tool_1.SandboxInit,
215
+ sandbox_tool_1.SandboxDestroy,
216
+ sandbox_filesystem_1.SandboxWriteFile,
217
+ sandbox_filesystem_1.SandboxReadFile,
218
+ sandbox_filesystem_1.SandboxListDirectory,
219
+ sandbox_filesystem_1.SandboxCreateDirectory,
220
+ sandbox_filesystem_1.SandboxDelete,
221
+ sandbox_filesystem_1.SandboxExists,
222
+ sandbox_filesystem_1.SandboxFileInfo])
223
+ ], SandboxExampleWorkflow);
224
+ //# sourceMappingURL=sandbox-example.workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-example.workflow.js","sourceRoot":"","sources":["../../../src/workflows/sandbox/sandbox-example.workflow.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@loopstack/filesystem-examples",
3
+ "displayName": "Loopstack Filesystem Examples",
4
+ "description": "Workflow examples for filesystem operations in Loopstack — Docker sandbox, remote file browsing, remote command execution, and local file tree.",
5
+ "keywords": [
6
+ "loopstack",
7
+ "example",
8
+ "filesystem",
9
+ "sandbox",
10
+ "remote",
11
+ "workflow"
12
+ ],
13
+ "version": "0.1.1",
14
+ "license": "MIT",
15
+ "author": {
16
+ "name": "Jakob Klippel",
17
+ "url": "https://www.linkedin.com/in/jakob-klippel/"
18
+ },
19
+ "main": "dist/index.js",
20
+ "types": "dist/index.d.ts",
21
+ "exports": {
22
+ ".": "./dist/index.js",
23
+ "./src/*": "./src/*"
24
+ },
25
+ "scripts": {
26
+ "build": "nest build",
27
+ "compile": "tsc --noEmit",
28
+ "format": "prettier --write .",
29
+ "lint": "eslint .",
30
+ "test": "vitest run --passWithNoTests",
31
+ "watch": "nest build --watch"
32
+ },
33
+ "dependencies": {
34
+ "@loopstack/common": "*",
35
+ "@loopstack/local-file-explorer-module": "*",
36
+ "@loopstack/remote-client": "*",
37
+ "@loopstack/remote-file-explorer-module": "*",
38
+ "@loopstack/sandbox-filesystem": "*",
39
+ "@loopstack/sandbox-tool": "*",
40
+ "@nestjs/common": "^11.1.19",
41
+ "zod": "^4.3.6"
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "src"
46
+ ],
47
+ "devDependencies": {
48
+ "vitest": "^4.1.6",
49
+ "@swc/core": "^1.15.33",
50
+ "unplugin-swc": "^1.5.9"
51
+ }
52
+ }
@@ -0,0 +1,35 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { StudioApp } from '@loopstack/common';
3
+ import { LocalFileExplorerModule } from '@loopstack/local-file-explorer-module';
4
+ import { RemoteClientModule } from '@loopstack/remote-client';
5
+ import { RemoteFileExplorerModule } from '@loopstack/remote-file-explorer-module';
6
+ import { SandboxFilesystemModule } from '@loopstack/sandbox-filesystem';
7
+ import { SandboxToolModule } from '@loopstack/sandbox-tool';
8
+ import { LocalFileExplorerExampleWorkflow } from './workflows/local-file-explorer/local-file-explorer-example.workflow';
9
+ import { RemoteClientExampleWorkflow } from './workflows/remote-client/remote-client-example.workflow';
10
+ import { RemoteFileExplorerExampleWorkflow } from './workflows/remote-file-explorer/remote-file-explorer-example.workflow';
11
+ import { SandboxExampleWorkflow } from './workflows/sandbox/sandbox-example.workflow';
12
+
13
+ const WORKFLOWS = [
14
+ SandboxExampleWorkflow,
15
+ RemoteFileExplorerExampleWorkflow,
16
+ RemoteClientExampleWorkflow,
17
+ LocalFileExplorerExampleWorkflow,
18
+ ];
19
+
20
+ @StudioApp({
21
+ title: 'Filesystem Examples',
22
+ workflows: WORKFLOWS,
23
+ })
24
+ @Module({
25
+ imports: [
26
+ SandboxFilesystemModule,
27
+ SandboxToolModule,
28
+ RemoteFileExplorerModule.forFeature(),
29
+ RemoteClientModule.forFeature({ slots: [{ id: 'sandbox', type: 'sandbox', title: 'Sandbox' }] }),
30
+ LocalFileExplorerModule.forFeature(),
31
+ ],
32
+ providers: WORKFLOWS,
33
+ exports: WORKFLOWS,
34
+ })
35
+ export class FilesystemExamplesModule {}
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './filesystem-examples.module';
2
+ export * from './workflows/sandbox/sandbox-example.workflow';
3
+ export * from './workflows/remote-file-explorer/remote-file-explorer-example.workflow';
4
+ export * from './workflows/remote-client/remote-client-example.workflow';
5
+ export * from './workflows/local-file-explorer/local-file-explorer-example.workflow';
@@ -0,0 +1,34 @@
1
+ import { BaseWorkflow, MarkdownDocument, Transition, Workflow } from '@loopstack/common';
2
+ import { FileSystemService } from '@loopstack/local-file-explorer-module';
3
+
4
+ interface LocalFileExplorerState {
5
+ fileCount?: number;
6
+ }
7
+
8
+ @Workflow({
9
+ title: 'Filesystem - Local File Explorer Example',
10
+ description:
11
+ 'Demonstrates @loopstack/local-file-explorer-module — uses FileSystemService to build a file tree of the workspace root and render it as markdown. The module also exposes a REST API for the Studio file panel.',
12
+ })
13
+ export class LocalFileExplorerExampleWorkflow extends BaseWorkflow {
14
+ constructor(private readonly fileSystem: FileSystemService) {
15
+ super();
16
+ }
17
+
18
+ @Transition({ to: 'end' })
19
+ async listTree(_state: LocalFileExplorerState) {
20
+ const tree = await this.fileSystem.buildFileTree(process.cwd());
21
+ const lines = tree.slice(0, 50).map((node) => `- ${node.path} (${node.type})`);
22
+
23
+ await this.documentStore.save(MarkdownDocument, {
24
+ markdown: [
25
+ `# Workspace File Tree`,
26
+ '',
27
+ `Found ${tree.length} top-level entries in \`${process.cwd()}\`.`,
28
+ '',
29
+ ...lines,
30
+ tree.length > 50 ? `\n_(${tree.length - 50} more entries omitted)_` : '',
31
+ ].join('\n'),
32
+ });
33
+ }
34
+ }
@@ -0,0 +1,57 @@
1
+ import { BaseWorkflow, MessageDocument, Transition, Workflow } from '@loopstack/common';
2
+ import { BashTool, ReadTool, WriteTool } from '@loopstack/remote-client';
3
+
4
+ interface RemoteClientState {
5
+ filePath?: string;
6
+ }
7
+
8
+ @Workflow({
9
+ title: 'Filesystem - Remote Client Example',
10
+ description:
11
+ 'Demonstrates @loopstack/remote-client tools beyond file browsing: write a file, run a shell command on the remote machine via BashTool, read the result. Useful when you need command execution against a remote workspace.',
12
+ })
13
+ export class RemoteClientExampleWorkflow extends BaseWorkflow {
14
+ constructor(
15
+ private readonly bash: BashTool,
16
+ private readonly read: ReadTool,
17
+ private readonly write: WriteTool,
18
+ ) {
19
+ super();
20
+ }
21
+
22
+ @Transition({ to: 'file_written' })
23
+ async writeFile(_state: RemoteClientState) {
24
+ const filePath = '/tmp/remote-client-example.txt';
25
+ await this.write.call({
26
+ file_path: filePath,
27
+ content: 'Hello from RemoteClientExampleWorkflow!\n',
28
+ });
29
+ await this.documentStore.save(MessageDocument, {
30
+ role: 'assistant',
31
+ text: `Wrote file ${filePath}.`,
32
+ });
33
+ this.assignState({ filePath });
34
+ }
35
+
36
+ @Transition({ from: 'file_written', to: 'command_executed' })
37
+ async runCommand(state: RemoteClientState) {
38
+ const result = await this.bash.call({
39
+ command: `wc -l ${state.filePath} && date`,
40
+ });
41
+ const stdout = (result.data as { stdout?: string })?.stdout ?? '';
42
+ await this.documentStore.save(MessageDocument, {
43
+ role: 'assistant',
44
+ text: `Command output:\n\`\`\`\n${stdout}\n\`\`\``,
45
+ });
46
+ }
47
+
48
+ @Transition({ from: 'command_executed', to: 'end' })
49
+ async readBack(state: RemoteClientState) {
50
+ const result = await this.read.call({ file_path: state.filePath! });
51
+ const content = (result.data as { content?: string })?.content ?? '';
52
+ await this.documentStore.save(MessageDocument, {
53
+ role: 'assistant',
54
+ text: `Final file content:\n\`\`\`\n${content}\n\`\`\``,
55
+ });
56
+ }
57
+ }
@@ -0,0 +1,54 @@
1
+ import { BaseWorkflow, MessageDocument, Transition, Workflow } from '@loopstack/common';
2
+ import { GlobTool, ReadTool } from '@loopstack/remote-client';
3
+
4
+ interface RemoteFileExplorerState {
5
+ firstMatch?: string;
6
+ }
7
+
8
+ @Workflow({
9
+ title: 'Filesystem - Remote File Explorer Example',
10
+ description:
11
+ 'Browses a remote workspace via @loopstack/remote-client GlobTool + ReadTool — finds Markdown files, reads the first match.',
12
+ })
13
+ export class RemoteFileExplorerExampleWorkflow extends BaseWorkflow {
14
+ constructor(
15
+ private readonly glob: GlobTool,
16
+ private readonly read: ReadTool,
17
+ ) {
18
+ super();
19
+ }
20
+
21
+ @Transition({ to: 'listed' })
22
+ async listFiles(_state: RemoteFileExplorerState) {
23
+ const result = await this.glob.call({ pattern: '**/*.md' });
24
+ const files = (result.data as { files?: string[] })?.files ?? [];
25
+
26
+ await this.documentStore.save(MessageDocument, {
27
+ role: 'assistant',
28
+ text: `Found ${files.length} markdown files:\n${files
29
+ .slice(0, 20)
30
+ .map((f) => `- ${f}`)
31
+ .join('\n')}`,
32
+ });
33
+ this.assignState({ firstMatch: files[0] });
34
+ }
35
+
36
+ @Transition({ from: 'listed', to: 'end' })
37
+ async readFirst(state: RemoteFileExplorerState) {
38
+ if (!state.firstMatch) {
39
+ await this.documentStore.save(MessageDocument, {
40
+ role: 'assistant',
41
+ text: 'No markdown files to read.',
42
+ });
43
+ return;
44
+ }
45
+
46
+ const result = await this.read.call({ file_path: state.firstMatch });
47
+ const content = (result.data as { content?: string })?.content ?? '';
48
+
49
+ await this.documentStore.save(MessageDocument, {
50
+ role: 'assistant',
51
+ text: `# ${state.firstMatch}\n\n${content.slice(0, 500)}`,
52
+ });
53
+ }
54
+ }
@@ -0,0 +1,194 @@
1
+ import { z } from 'zod';
2
+ import { BaseWorkflow, MessageDocument, Transition, Workflow } from '@loopstack/common';
3
+ import type { RunContext } from '@loopstack/common';
4
+ import {
5
+ SandboxCreateDirectory,
6
+ SandboxDelete,
7
+ SandboxExists,
8
+ SandboxFileInfo,
9
+ SandboxListDirectory,
10
+ SandboxReadFile,
11
+ SandboxWriteFile,
12
+ } from '@loopstack/sandbox-filesystem';
13
+ import { SandboxDestroy, SandboxInit } from '@loopstack/sandbox-tool';
14
+
15
+ interface FileEntry {
16
+ name: string;
17
+ type: string;
18
+ size: number;
19
+ path: string;
20
+ }
21
+
22
+ interface SandboxExampleState {
23
+ containerId?: string;
24
+ fileContent?: string;
25
+ fileList?: FileEntry[];
26
+ }
27
+
28
+ const SandboxExampleArgsSchema = z.object({
29
+ outputDir: z.string().default(process.cwd() + '/out'),
30
+ });
31
+
32
+ type SandboxExampleArgs = z.infer<typeof SandboxExampleArgsSchema>;
33
+
34
+ @Workflow({
35
+ title: 'Filesystem - Sandbox Example',
36
+ description:
37
+ 'Demonstrates the full Docker sandbox lifecycle: init a container, perform file operations (write, read, list, delete), and destroy the sandbox. Useful for isolated execution of untrusted code.',
38
+ schema: SandboxExampleArgsSchema,
39
+ })
40
+ export class SandboxExampleWorkflow extends BaseWorkflow<SandboxExampleArgs> {
41
+ constructor(
42
+ // Sandbox lifecycle tools (from @loopstack/sandbox-tool)
43
+ private readonly sandboxInit: SandboxInit,
44
+ private readonly sandboxDestroy: SandboxDestroy,
45
+ // Filesystem tools (from @loopstack/sandbox-filesystem)
46
+ private readonly sandboxWriteFile: SandboxWriteFile,
47
+ private readonly sandboxReadFile: SandboxReadFile,
48
+ private readonly sandboxListDirectory: SandboxListDirectory,
49
+ private readonly sandboxCreateDirectory: SandboxCreateDirectory,
50
+ private readonly sandboxDelete: SandboxDelete,
51
+ private readonly sandboxExists: SandboxExists,
52
+ private readonly sandboxFileInfo: SandboxFileInfo,
53
+ ) {
54
+ super();
55
+ }
56
+
57
+ @Transition({ to: 'sandbox_ready' })
58
+ async initSandbox(state: SandboxExampleState, ctx: RunContext<SandboxExampleArgs>) {
59
+ const initResult = await this.sandboxInit.call({
60
+ containerId: 'my-sandbox',
61
+ imageName: 'node:18',
62
+ containerName: 'my-filesystem-sandbox',
63
+ projectOutPath: ctx.args.outputDir,
64
+ rootPath: 'workspace',
65
+ });
66
+
67
+ await this.documentStore.save(MessageDocument, {
68
+ role: 'assistant',
69
+ text: `Sandbox initialized successfully. Container ID: ${initResult.data.containerId}, Docker ID: ${initResult.data.dockerId}`,
70
+ });
71
+ this.assignState({ containerId: initResult.data.containerId });
72
+ }
73
+
74
+ @Transition({ from: 'sandbox_ready', to: 'dir_created' })
75
+ async createDir(state: SandboxExampleState) {
76
+ const mkdirResult = await this.sandboxCreateDirectory.call({
77
+ containerId: state.containerId!,
78
+ path: '/workspace',
79
+ recursive: true,
80
+ });
81
+
82
+ await this.documentStore.save(MessageDocument, {
83
+ role: 'assistant',
84
+ text: `Directory created: ${mkdirResult.data.path} (created: ${mkdirResult.data.created})`,
85
+ });
86
+ }
87
+
88
+ @Transition({ from: 'dir_created', to: 'file_written' })
89
+ async writeFile(state: SandboxExampleState) {
90
+ const writeResult = await this.sandboxWriteFile.call({
91
+ containerId: state.containerId!,
92
+ path: '/workspace/result.txt',
93
+ content: 'Hello from sandbox!',
94
+ encoding: 'utf8',
95
+ createParentDirs: true,
96
+ });
97
+
98
+ await this.documentStore.save(MessageDocument, {
99
+ role: 'assistant',
100
+ text: `File written: ${writeResult.data.path} (${writeResult.data.bytesWritten} bytes)`,
101
+ });
102
+ }
103
+
104
+ @Transition({ from: 'file_written', to: 'file_read' })
105
+ async readFile(state: SandboxExampleState) {
106
+ const readResult = await this.sandboxReadFile.call({
107
+ containerId: state.containerId!,
108
+ path: '/workspace/result.txt',
109
+ encoding: 'utf8',
110
+ });
111
+
112
+ await this.documentStore.save(MessageDocument, {
113
+ role: 'assistant',
114
+ text: `File read successfully. Content: "${readResult.data.content}" (encoding: ${readResult.data.encoding})`,
115
+ });
116
+ this.assignState({ fileContent: readResult.data.content });
117
+ }
118
+
119
+ @Transition({ from: 'file_read', to: 'dir_listed' })
120
+ async listDir(state: SandboxExampleState) {
121
+ const listResult = await this.sandboxListDirectory.call({
122
+ containerId: state.containerId!,
123
+ path: '/workspace',
124
+ recursive: false,
125
+ });
126
+
127
+ await this.documentStore.save(MessageDocument, {
128
+ role: 'assistant',
129
+ text: `Directory listing for ${listResult.data.path}: ${this.formatEntries(listResult.data.entries)}`,
130
+ });
131
+ this.assignState({ fileList: listResult.data.entries });
132
+ }
133
+
134
+ @Transition({ from: 'dir_listed', to: 'existence_checked' })
135
+ async checkExists(state: SandboxExampleState) {
136
+ const existsResult = await this.sandboxExists.call({
137
+ containerId: state.containerId!,
138
+ path: '/workspace/result.txt',
139
+ });
140
+
141
+ await this.documentStore.save(MessageDocument, {
142
+ role: 'assistant',
143
+ text: `File existence check: ${existsResult.data.path} exists=${existsResult.data.exists}, type=${existsResult.data.type}`,
144
+ });
145
+ }
146
+
147
+ @Transition({ from: 'existence_checked', to: 'info_retrieved' })
148
+ async getInfo(state: SandboxExampleState) {
149
+ const infoResult = await this.sandboxFileInfo.call({
150
+ containerId: state.containerId!,
151
+ path: '/workspace/result.txt',
152
+ });
153
+
154
+ await this.documentStore.save(MessageDocument, {
155
+ role: 'assistant',
156
+ text: `File info for ${infoResult.data.name}: type=${infoResult.data.type}, size=${infoResult.data.size} bytes, permissions=${infoResult.data.permissions}, owner=${infoResult.data.owner}`,
157
+ });
158
+ }
159
+
160
+ @Transition({ from: 'info_retrieved', to: 'file_deleted' })
161
+ async deleteFile(state: SandboxExampleState) {
162
+ const deleteResult = await this.sandboxDelete.call({
163
+ containerId: state.containerId!,
164
+ path: '/workspace/result.txt',
165
+ recursive: false,
166
+ force: true,
167
+ });
168
+
169
+ await this.documentStore.save(MessageDocument, {
170
+ role: 'assistant',
171
+ text: `File deleted: ${deleteResult.data.path} (deleted: ${deleteResult.data.deleted})`,
172
+ });
173
+ }
174
+
175
+ @Transition({ from: 'file_deleted', to: 'end' })
176
+ async destroySandbox(state: SandboxExampleState) {
177
+ const destroyResult = await this.sandboxDestroy.call({
178
+ containerId: state.containerId!,
179
+ removeContainer: true,
180
+ });
181
+
182
+ await this.documentStore.save(MessageDocument, {
183
+ role: 'assistant',
184
+ text: `Sandbox destroyed. Container ${destroyResult.data.containerId} removed=${destroyResult.data.removed}`,
185
+ });
186
+ }
187
+
188
+ private formatEntries(entries: FileEntry[]): string {
189
+ if (!entries || entries.length === 0) {
190
+ return '(empty)';
191
+ }
192
+ return entries.map((e) => `${e.name} (${e.type}, ${e.size} bytes)`).join(', ');
193
+ }
194
+ }