runwork 0.27.1 → 0.28.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/README.md +61 -2
- package/bundled-types/channels.d.ts +17 -0
- package/bundled-types/core-channels.d.ts +11 -10
- package/bundled-types/core-events.d.ts +3 -2
- package/bundled-types/core-workspace.d.ts +28 -0
- package/dist/index.js +27032 -19333
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Runwork is an AI workspace that brings AI agents, custom apps, and human teams i
|
|
|
8
8
|
|
|
9
9
|
This CLI is the local development interface to the platform. You write TypeScript, and the platform handles deployment, infrastructure, AI, and integrations:
|
|
10
10
|
|
|
11
|
-
- **Full-stack apps, zero infrastructure** -- Data storage, file hosting, background jobs, durable workflows, AI, and
|
|
11
|
+
- **Full-stack apps, zero infrastructure** -- Data storage, file hosting, background jobs, durable workflows, AI, and thousands of third-party integrations are all built into the platform. You write application code; Runwork runs it.
|
|
12
12
|
- **Zero to app in seconds** -- Describe what you need and Runwork generates it. Developers customize with code using the [`@runworkai/framework`](https://www.npmjs.com/package/@runworkai/framework).
|
|
13
13
|
- **Instant deployments** -- Push code and get a live URL. Preview environments while you develop, production at the edge.
|
|
14
14
|
- **Built-in AI agents** -- Conversational agents that read data, take actions, and coordinate across apps. No API keys or model configuration to manage.
|
|
@@ -57,6 +57,7 @@ runwork dev # Start developing with live preview
|
|
|
57
57
|
| `runwork clone` | Clone an existing Runwork app to your machine |
|
|
58
58
|
| `runwork dev` | Start local development with live preview and auto-sync |
|
|
59
59
|
| `runwork deploy` | Deploy to production |
|
|
60
|
+
| `runwork spaces` | Spaces: containers for one kind of work |
|
|
60
61
|
| `runwork logout` | Remove stored credentials |
|
|
61
62
|
|
|
62
63
|
### `runwork dev`
|
|
@@ -72,6 +73,64 @@ The main development command. When you run `runwork dev`:
|
|
|
72
73
|
|
|
73
74
|
Edit files in your editor, and changes appear in the preview automatically.
|
|
74
75
|
|
|
76
|
+
Preview data lives inside the sandbox. Every entity starts empty again after the sandbox is
|
|
77
|
+
replaced, which a restart or a recycled container can both do. Your production data is untouched.
|
|
78
|
+
|
|
79
|
+
### `runwork spaces`
|
|
80
|
+
|
|
81
|
+
A space is a container for one kind of work: its files, AI instructions, skills, apps, automations
|
|
82
|
+
and conversations. `runwork spaces map` keeps a local folder in a space, so what you share is
|
|
83
|
+
uploaded for members of the space to read and conversations you run there are filed under the space
|
|
84
|
+
on this machine.
|
|
85
|
+
|
|
86
|
+
| Subcommand | Description |
|
|
87
|
+
|------------|-------------|
|
|
88
|
+
| `spaces suggest` | Propose spaces and things to keep in them from your local conversations (nothing is uploaded) |
|
|
89
|
+
| `spaces list` | Spaces in the workspace, with the folders on this machine mapped to each |
|
|
90
|
+
| `spaces map <folder>` | Keep a folder in a space: everything in it waits in Changes for you to share, and what you share is uploaded for members of the space to read. Conversations you run there are filed under the space on this machine, not uploaded |
|
|
91
|
+
| `spaces scope <folder>` | What a folder would share with a space, before you map it. Maps nothing and writes nothing |
|
|
92
|
+
| `spaces create <name>` | Create a space |
|
|
93
|
+
| `spaces default-folder [space]` | Where this space's folder would go on this machine if nobody chose. Creates nothing and maps nothing. |
|
|
94
|
+
| `spaces contents [space]` | What is filed under a space: its apps, skills, chats, workflows and endpoints |
|
|
95
|
+
| `spaces ls [space] [path]` | The files a space holds, as a teammate on another machine would see them |
|
|
96
|
+
| `spaces cat [space] <path>` | Print a file the space holds, as it is now or as it was at an earlier commit |
|
|
97
|
+
| `spaces history [space] <path>` | Who changed a file in a space and when, newest first, with the commit each version can be read at |
|
|
98
|
+
| `spaces put [space] <path> [file]` | Write any file into a space, from a local file or from stdin |
|
|
99
|
+
| `spaces rm [space] <path>` | Take a file out of a space. Its history stays, so a teammate can still see what it was. |
|
|
100
|
+
| `spaces instructions [space] [file]` | Read a space's `AGENTS.md`, or replace it from a local file or stdin |
|
|
101
|
+
| `spaces files [path]` | What is in a mapped folder, and which of it the space shares |
|
|
102
|
+
| `spaces include <path>` | Share a file or folder from a mapped folder with its space |
|
|
103
|
+
| `spaces exclude <path...>` | Stop sharing a file or folder, and take it out of the space |
|
|
104
|
+
| `spaces pause <folder>` | Stop this folder sharing on its own: its changes wait for runwork spaces share. Teammates' changes still arrive |
|
|
105
|
+
| `spaces resume <folder>` | Let this folder share its changes on its own, as each file stops changing |
|
|
106
|
+
| `spaces changes [folder]` | What this folder would send to its space next, and what is holding each of it back |
|
|
107
|
+
| `spaces sync [folder]` | Bring mapped folders and their spaces together: commit local changes, push, and pull what teammates added (no system git needed). With no folder named it syncs the mapped folder you are standing in; `--all` syncs every one of them |
|
|
108
|
+
| `spaces share [folder] [path...]` | Share what is waiting in a mapped folder now, without waiting for files to settle. Name any number of paths to share exactly those |
|
|
109
|
+
| `spaces launched <folder>` | Record that a conversation was just opened from this folder's space, so a cloud session with several space folders connected knows which one this is about |
|
|
110
|
+
| `spaces unmap <folder>` | Stop filing a folder under a space (this machine only) |
|
|
111
|
+
| `spaces reset <folder>` | Throw away this machine's copy of a mapped folder's space history, so the next sync rebuilds it from the space |
|
|
112
|
+
| `spaces prune` | Remove space histories on this machine that no folder maps to any more |
|
|
113
|
+
| `spaces mappings` | Folder-to-space mappings on this machine, the one you are standing in first |
|
|
114
|
+
|
|
115
|
+
`spaces rm` is also available as `spaces delete`. A mapped folder shares nothing until you ask for
|
|
116
|
+
it: run `spaces changes` to see what is waiting and `spaces share` to send it. Pass `--auto` to
|
|
117
|
+
`spaces map`, or run `spaces resume`, to have a folder share each file on its own once the file
|
|
118
|
+
stops changing.
|
|
119
|
+
|
|
120
|
+
Anything that files something under a space takes that space from the folder you are in when it is
|
|
121
|
+
mapped to one: `init`, `skills push`, `skills install`, `save-convo` and `share-convo`. `--space`
|
|
122
|
+
always wins, and each of them says which space it chose and why.
|
|
123
|
+
|
|
124
|
+
The verbs above that act on a space take it the same way, so inside a mapped folder `spaces ls`,
|
|
125
|
+
`spaces cat notes/plan.md` and `spaces contents` are about that folder's space. Naming the space
|
|
126
|
+
still works everywhere and still wins. How many arguments you give decides what they mean, so an
|
|
127
|
+
existing command keeps meaning what it always did: one argument to `ls` and `instructions` is the
|
|
128
|
+
space, and two to `put` are the space and the path. `cat`, `history` and `rm` read a single argument
|
|
129
|
+
as the path, and `put` takes the space from the folder when it is given a path alone, with the
|
|
130
|
+
content piped in (`runwork spaces put notes/plan.md < ./plan.md`). Reading falls back to your
|
|
131
|
+
personal space when the folder is mapped to nothing; `put`, `rm` and `instructions` ask you to name
|
|
132
|
+
one instead, because a write must not land somewhere nobody pointed at.
|
|
133
|
+
|
|
75
134
|
## How It Works
|
|
76
135
|
|
|
77
136
|
Runwork apps are full-stack TypeScript projects built with the [`@runworkai/framework`](https://www.npmjs.com/package/@runworkai/framework). The CLI handles the development lifecycle:
|
|
@@ -93,7 +152,7 @@ Every Runwork app gets built-in access to:
|
|
|
93
152
|
- **File storage** -- Upload and manage files and media
|
|
94
153
|
- **Public endpoints** -- Authenticated APIs for external consumers
|
|
95
154
|
- **Cross-app workspaces** -- Shared entities, channels, and notifications between apps
|
|
96
|
-
- **
|
|
155
|
+
- **Third-party integrations** -- OAuth-managed connections to third-party services
|
|
97
156
|
|
|
98
157
|
## Project Structure
|
|
99
158
|
|
|
@@ -1,2 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel: `@runworkai/framework/channels` (retired).
|
|
3
|
+
*
|
|
4
|
+
* Kept so apps built against earlier versions keep compiling. The notices below
|
|
5
|
+
* are JSDoc rather than line comments on purpose: tsc drops `//` comments from
|
|
6
|
+
* the emitted `.d.ts`, and these declarations are what every local agent reads
|
|
7
|
+
* out of `.runwork/types/`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Channels are retired. This still posts to the workspace event
|
|
11
|
+
* stream, where the message appears in the activity feed and on the app's
|
|
12
|
+
* timeline, so deployed apps keep working. Use `emitEvent` from
|
|
13
|
+
* `@runworkai/framework/events` for new code.
|
|
14
|
+
*/
|
|
1
15
|
export { postToChannel } from './core-channels';
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Channels are retired; see `postToChannel`.
|
|
18
|
+
*/
|
|
2
19
|
export type { PostToChannelParams } from './core-channels';
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Core Channels
|
|
2
|
+
* Core Channels (retired)
|
|
3
3
|
* DO NOT MODIFY THIS FILE - You may break the project functionality
|
|
4
4
|
*
|
|
5
|
-
* This module
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Workspace channels no longer exist. This module stays only so apps built
|
|
6
|
+
* against earlier framework versions keep working: `postToChannel()` still
|
|
7
|
+
* sends its message to the platform, which files it as an app event in the
|
|
8
|
+
* workspace activity feed and on the app's timeline. New code should call
|
|
9
|
+
* `emitEvent()` from `@runworkai/framework/events` instead.
|
|
9
10
|
* When running outside a workspace (standalone mode), calls are silently skipped.
|
|
10
11
|
*/
|
|
12
|
+
/** @deprecated Channels are retired; use `emitEvent()` from `@runworkai/framework/events`. */
|
|
11
13
|
export interface PostToChannelParams {
|
|
12
|
-
/**
|
|
14
|
+
/** Former channel name; kept for compatibility and ignored by the platform. */
|
|
13
15
|
channel: string;
|
|
14
16
|
/** Markdown message content */
|
|
15
17
|
content: string;
|
|
@@ -31,12 +33,11 @@ interface ChannelEnv {
|
|
|
31
33
|
*/
|
|
32
34
|
type WaitUntilContext = Pick<ExecutionContext, 'waitUntil'>;
|
|
33
35
|
/**
|
|
34
|
-
*
|
|
36
|
+
* @deprecated Channels are retired. The message is still delivered as an app
|
|
37
|
+
* event that appears in the workspace activity feed and on the app's timeline;
|
|
38
|
+
* use `emitEvent()` from `@runworkai/framework/events` for new code.
|
|
35
39
|
* Fire-and-forget: uses ctx.waitUntil so it doesn't block the response.
|
|
36
40
|
* Silently skips if workspace env vars are not configured (standalone mode).
|
|
37
|
-
*
|
|
38
|
-
* Channels are auto-created on first use. The channel will automatically
|
|
39
|
-
* include this app's system events via filter projection.
|
|
40
41
|
*/
|
|
41
42
|
export declare function postToChannel(ctx: WaitUntilContext, env: ChannelEnv, params: PostToChannelParams): void;
|
|
42
43
|
export {};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - emitEvent(): Fire-and-forget event emission to the workspace event stream
|
|
7
7
|
* - flog(): Structured logging that outputs JSON to sandbox stdout
|
|
8
8
|
*
|
|
9
|
-
* Events appear in the workspace activity feed and
|
|
9
|
+
* Events appear in the workspace activity feed and on the app's timeline.
|
|
10
10
|
* When running outside a workspace (standalone mode), calls are silently skipped.
|
|
11
11
|
*/
|
|
12
12
|
export interface EmitEventParams {
|
|
@@ -31,7 +31,8 @@ interface EventEnv {
|
|
|
31
31
|
*/
|
|
32
32
|
type WaitUntilContext = Pick<ExecutionContext, 'waitUntil'>;
|
|
33
33
|
/**
|
|
34
|
-
* Convert an app name to
|
|
34
|
+
* Convert an app name to the kebab-case label the legacy `channel` field carries.
|
|
35
|
+
* @deprecated Channels are retired; the platform ignores the field.
|
|
35
36
|
* "My Cool App" -> "my-cool-app"
|
|
36
37
|
*/
|
|
37
38
|
export declare function toChannelName(appName: string): string;
|
|
@@ -89,6 +89,15 @@ export interface RegisterEntityRequest extends Record<string, unknown> {
|
|
|
89
89
|
schema?: Record<string, unknown>;
|
|
90
90
|
deploymentMode?: 'preview' | 'production';
|
|
91
91
|
}
|
|
92
|
+
export interface RegisterAllEntitiesRequest extends Record<string, unknown> {
|
|
93
|
+
appId: string;
|
|
94
|
+
appName: string;
|
|
95
|
+
entities: Array<{
|
|
96
|
+
entityName: string;
|
|
97
|
+
schema?: Record<string, unknown>;
|
|
98
|
+
}>;
|
|
99
|
+
deploymentMode?: 'preview' | 'production';
|
|
100
|
+
}
|
|
92
101
|
export interface RegisterAppRequest extends Record<string, unknown> {
|
|
93
102
|
appId: string;
|
|
94
103
|
appName: string;
|
|
@@ -269,6 +278,19 @@ export declare class WorkspaceContext {
|
|
|
269
278
|
* Register an entity with the workspace so other apps can query it
|
|
270
279
|
*/
|
|
271
280
|
registerEntity(entityName: string, schema?: Record<string, unknown>): Promise<void>;
|
|
281
|
+
/**
|
|
282
|
+
* Register every entity this app defines in one call.
|
|
283
|
+
*
|
|
284
|
+
* Ownership rules are the same as registerEntity (first registrant owns,
|
|
285
|
+
* later apps are recorded as references, preview never touches production),
|
|
286
|
+
* but the workspace applies them in a single state write instead of one per
|
|
287
|
+
* entity. A platform that predates the bulk route answers 404; then each
|
|
288
|
+
* entity is registered individually so an older platform keeps working.
|
|
289
|
+
*/
|
|
290
|
+
registerAllEntities(entities: Array<{
|
|
291
|
+
entityName: string;
|
|
292
|
+
schema?: Record<string, unknown>;
|
|
293
|
+
}>): Promise<void>;
|
|
272
294
|
/**
|
|
273
295
|
* Register this app with the workspace (safe to call multiple times)
|
|
274
296
|
*/
|
|
@@ -545,3 +567,9 @@ export declare function deleteWorkspaceEntity(env: Env, entityName: string, id:
|
|
|
545
567
|
* Called once when the worker starts
|
|
546
568
|
*/
|
|
547
569
|
export declare function initializeWorkspace(env: Env): Promise<void>;
|
|
570
|
+
/**
|
|
571
|
+
* Forget that this isolate is initialized so the next request runs a sweep
|
|
572
|
+
* again. The last successful fingerprint is kept: a sweep that finds the
|
|
573
|
+
* definitions unchanged completes without calling the workspace.
|
|
574
|
+
*/
|
|
575
|
+
export declare function invalidateWorkspaceInitialization(): void;
|