@shadowob/cloud 1.1.6-dev.311 → 1.1.6

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  collectRuntimeEnvRequirements
3
- } from "./chunk-SUZ2ATT6.js";
3
+ } from "./chunk-FSW4TNHN.js";
4
4
 
5
5
  // src/interfaces/cli/init.command.ts
6
6
  import { cp, stat, writeFile } from "fs/promises";
@@ -611,6 +611,7 @@ var RUNNER_STATE_VOLUME_NAME = "shadow-runner-state";
611
611
  var RUNNER_LOG_VOLUME_NAME = "shadow-runner-logs";
612
612
  var RUNNER_CONFIG_VOLUME_NAME = "shadow-runner-config";
613
613
  var RUNNER_TMP_VOLUME_NAME = "shadow-runner-tmp";
614
+ var RUNNER_AGENTS_VOLUME_NAME = "shadow-runner-agents";
614
615
  var NATIVE_RUNNER_HEALTH_PORT = 3100;
615
616
  var OPENCLAW_GATEWAY_PORT = 3101;
616
617
  var OPENCLAW_HEALTH_PORT = 3102;
@@ -788,13 +789,20 @@ function buildIdentityWorkspaceFiles(agent) {
788
789
  }
789
790
  function shadowobSkillMarkdown() {
790
791
  const here = dirname(fileURLToPath(import.meta.url));
791
- const candidates = [
792
- resolve(process.cwd(), "skills/shadowob-cli/SKILL.md"),
793
- resolve(process.cwd(), "../skills/shadowob-cli/SKILL.md"),
794
- resolve(here, "../../../../skills/shadowob-cli/SKILL.md"),
795
- resolve(here, "../../../../../skills/shadowob-cli/SKILL.md")
796
- ];
797
- const path = candidates.find((candidate) => existsSync(candidate));
792
+ let currentDir = here;
793
+ let path;
794
+ while (true) {
795
+ const candidate = resolve(currentDir, "skills/shadowob-cli/SKILL.md");
796
+ if (existsSync(candidate)) {
797
+ path = candidate;
798
+ break;
799
+ }
800
+ const parentDir = dirname(currentDir);
801
+ if (parentDir === currentDir) {
802
+ break;
803
+ }
804
+ currentDir = parentDir;
805
+ }
798
806
  if (!path) {
799
807
  throw new Error("Cannot find skills/shadowob-cli/SKILL.md for runner package generation");
800
808
  }
@@ -5755,6 +5763,7 @@ export {
5755
5763
  RUNNER_LOG_VOLUME_NAME,
5756
5764
  RUNNER_CONFIG_VOLUME_NAME,
5757
5765
  RUNNER_TMP_VOLUME_NAME,
5766
+ RUNNER_AGENTS_VOLUME_NAME,
5758
5767
  runtimeStatePvcName,
5759
5768
  getRuntime,
5760
5769
  getAllRuntimes,
@@ -14,7 +14,7 @@ function createConsoleCommand(container) {
14
14
  });
15
15
  }, 1500);
16
16
  }
17
- const { createServeCommand } = await import("./serve.command-DNE6GPMK.js");
17
+ const { createServeCommand } = await import("./serve.command-Q46LHQG6.js");
18
18
  const serve = createServeCommand(container);
19
19
  await serve.parseAsync(
20
20
  ["--port", port, "--namespace", ...options.namespace, "--host", "127.0.0.1"],
@@ -7,7 +7,7 @@ import {
7
7
  normalizeDeploymentRuntimeContext,
8
8
  parseJsonc,
9
9
  runtimeStatePvcName
10
- } from "./chunk-SUZ2ATT6.js";
10
+ } from "./chunk-FSW4TNHN.js";
11
11
  import {
12
12
  getPluginRegistry,
13
13
  loadAllPlugins
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  collectRuntimeEnvRequirements
4
- } from "./chunk-QET4LT4J.js";
4
+ } from "./chunk-ULOJLXQV.js";
5
5
 
6
6
  // src/interfaces/cli/init.command.ts
7
7
  import { cp, stat, writeFile } from "fs/promises";
@@ -16,7 +16,7 @@ function createConsoleCommand(container) {
16
16
  });
17
17
  }, 1500);
18
18
  }
19
- const { createServeCommand } = await import("./serve.command-5FMIPQRY.js");
19
+ const { createServeCommand } = await import("./serve.command-2AHJI665.js");
20
20
  const serve = createServeCommand(container);
21
21
  await serve.parseAsync(
22
22
  ["--port", port, "--namespace", ...options.namespace, "--host", "127.0.0.1"],
@@ -608,6 +608,7 @@ var RUNNER_STATE_VOLUME_NAME = "shadow-runner-state";
608
608
  var RUNNER_LOG_VOLUME_NAME = "shadow-runner-logs";
609
609
  var RUNNER_CONFIG_VOLUME_NAME = "shadow-runner-config";
610
610
  var RUNNER_TMP_VOLUME_NAME = "shadow-runner-tmp";
611
+ var RUNNER_AGENTS_VOLUME_NAME = "shadow-runner-agents";
611
612
  var NATIVE_RUNNER_HEALTH_PORT = 3100;
612
613
  var OPENCLAW_GATEWAY_PORT = 3101;
613
614
  var OPENCLAW_HEALTH_PORT = 3102;
@@ -785,13 +786,20 @@ function buildIdentityWorkspaceFiles(agent) {
785
786
  }
786
787
  function shadowobSkillMarkdown() {
787
788
  const here = dirname(fileURLToPath(import.meta.url));
788
- const candidates = [
789
- resolve(process.cwd(), "skills/shadowob-cli/SKILL.md"),
790
- resolve(process.cwd(), "../skills/shadowob-cli/SKILL.md"),
791
- resolve(here, "../../../../skills/shadowob-cli/SKILL.md"),
792
- resolve(here, "../../../../../skills/shadowob-cli/SKILL.md")
793
- ];
794
- const path = candidates.find((candidate) => existsSync(candidate));
789
+ let currentDir = here;
790
+ let path;
791
+ while (true) {
792
+ const candidate = resolve(currentDir, "skills/shadowob-cli/SKILL.md");
793
+ if (existsSync(candidate)) {
794
+ path = candidate;
795
+ break;
796
+ }
797
+ const parentDir = dirname(currentDir);
798
+ if (parentDir === currentDir) {
799
+ break;
800
+ }
801
+ currentDir = parentDir;
802
+ }
795
803
  if (!path) {
796
804
  throw new Error("Cannot find skills/shadowob-cli/SKILL.md for runner package generation");
797
805
  }
@@ -5746,6 +5754,7 @@ export {
5746
5754
  RUNNER_LOG_VOLUME_NAME,
5747
5755
  RUNNER_CONFIG_VOLUME_NAME,
5748
5756
  RUNNER_TMP_VOLUME_NAME,
5757
+ RUNNER_AGENTS_VOLUME_NAME,
5749
5758
  runtimeStatePvcName,
5750
5759
  parseJsonc,
5751
5760
  normalizeDeploymentRuntimeContext,
@@ -7,7 +7,7 @@ import {
7
7
  normalizeDeploymentRuntimeContext,
8
8
  parseJsonc,
9
9
  runtimeStatePvcName
10
- } from "./chunk-QET4LT4J.js";
10
+ } from "./chunk-ULOJLXQV.js";
11
11
  import {
12
12
  getPluginRegistry,
13
13
  loadAllPlugins
package/dist/cli.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createConsoleCommand
4
- } from "./chunk-QV4XWO3P.js";
4
+ } from "./chunk-SIDBK5SZ.js";
5
5
  import {
6
6
  createInitCommand
7
- } from "./chunk-KEPTCLUO.js";
7
+ } from "./chunk-IXN3FU5J.js";
8
8
  import {
9
9
  formatProvisionState,
10
10
  loadProvisionState,
@@ -17,8 +17,9 @@ import {
17
17
  resolveCloudPackageAssetDir,
18
18
  toProviderSecretEnvKey,
19
19
  withLegacyEnvAliases
20
- } from "./chunk-V2LU736V.js";
20
+ } from "./chunk-XFJX4NWN.js";
21
21
  import {
22
+ RUNNER_AGENTS_VOLUME_NAME,
22
23
  RUNNER_CONFIG_MOUNT_PATH,
23
24
  RUNNER_CONFIG_VOLUME_NAME,
24
25
  RUNNER_LOG_VOLUME_NAME,
@@ -42,7 +43,7 @@ import {
42
43
  resolveConfig,
43
44
  runtimeContextEnv,
44
45
  runtimeStatePvcName
45
- } from "./chunk-QET4LT4J.js";
46
+ } from "./chunk-ULOJLXQV.js";
46
47
  import {
47
48
  deepMerge,
48
49
  getPluginRegistry
@@ -1380,7 +1381,7 @@ function createOnboardCommand(container2) {
1380
1381
  } else {
1381
1382
  const answer = await ask(` No ${configPath} found. Create one from template? [Y/n] `);
1382
1383
  if (!answer || answer.toLowerCase() !== "n") {
1383
- const { createInitCommand: createInitCommand2 } = await import("./init.command-O4HG4HKR.js");
1384
+ const { createInitCommand: createInitCommand2 } = await import("./init.command-WGKN3GC6.js");
1384
1385
  const init = createInitCommand2(container2);
1385
1386
  await init.parseAsync(["--quick"], { from: "user" });
1386
1387
  } else {
@@ -1397,7 +1398,7 @@ function createOnboardCommand(container2) {
1397
1398
  }
1398
1399
  container2.logger.success("Onboarding complete! Starting console...");
1399
1400
  console.log();
1400
- const { createConsoleCommand: createConsoleCommand2 } = await import("./dashboard.command-J7XOZNXU.js");
1401
+ const { createConsoleCommand: createConsoleCommand2 } = await import("./dashboard.command-SCAAQ23X.js");
1401
1402
  const console_ = createConsoleCommand2(container2);
1402
1403
  await console_.parseAsync([], { from: "user" });
1403
1404
  });
@@ -4129,7 +4130,8 @@ function baseVolumeMounts(runtime) {
4129
4130
  { name: RUNNER_STATE_VOLUME_NAME, mountPath: runtime.container.statePath },
4130
4131
  { name: RUNNER_CONFIG_VOLUME_NAME, mountPath: RUNNER_CONFIG_MOUNT_PATH, readOnly: true },
4131
4132
  { name: RUNNER_LOG_VOLUME_NAME, mountPath: runtime.container.logPath },
4132
- { name: RUNNER_TMP_VOLUME_NAME, mountPath: "/tmp" }
4133
+ { name: RUNNER_TMP_VOLUME_NAME, mountPath: "/tmp" },
4134
+ { name: RUNNER_AGENTS_VOLUME_NAME, mountPath: "/workspace/.agents" }
4133
4135
  ];
4134
4136
  }
4135
4137
  function baseVolumes(configMapName) {
@@ -4137,7 +4139,8 @@ function baseVolumes(configMapName) {
4137
4139
  { name: RUNNER_STATE_VOLUME_NAME, emptyDir: {} },
4138
4140
  { name: RUNNER_CONFIG_VOLUME_NAME, configMap: { name: configMapName } },
4139
4141
  { name: RUNNER_LOG_VOLUME_NAME, emptyDir: {} },
4140
- { name: RUNNER_TMP_VOLUME_NAME, emptyDir: {} }
4142
+ { name: RUNNER_TMP_VOLUME_NAME, emptyDir: {} },
4143
+ { name: RUNNER_AGENTS_VOLUME_NAME, emptyDir: {} }
4141
4144
  ];
4142
4145
  }
4143
4146
  function buildAgentPodSpec(options) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createConsoleCommand
3
- } from "./chunk-TV3CBM7R.js";
3
+ } from "./chunk-HRTBOZ7O.js";
4
4
  import "./chunk-R5U7XKVJ.js";
5
5
  export {
6
6
  createConsoleCommand
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createConsoleCommand
4
- } from "./chunk-QV4XWO3P.js";
4
+ } from "./chunk-SIDBK5SZ.js";
5
5
  import "./chunk-AD3JTIU3.js";
6
6
  export {
7
7
  createConsoleCommand
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  createConsoleCommand
3
- } from "./chunk-TV3CBM7R.js";
3
+ } from "./chunk-HRTBOZ7O.js";
4
4
  import {
5
5
  createInitCommand
6
- } from "./chunk-R52J3PH2.js";
6
+ } from "./chunk-2FWJSE6Z.js";
7
7
  import {
8
8
  formatProvisionState,
9
9
  loadProvisionState,
@@ -26,8 +26,9 @@ import {
26
26
  toProviderSecretEnvKey,
27
27
  validateCloudSaasConfigSnapshot,
28
28
  withLegacyEnvAliases
29
- } from "./chunk-KKK5H7YX.js";
29
+ } from "./chunk-I3NRNCDR.js";
30
30
  import {
31
+ RUNNER_AGENTS_VOLUME_NAME,
31
32
  RUNNER_CONFIG_MOUNT_PATH,
32
33
  RUNNER_CONFIG_VOLUME_NAME,
33
34
  RUNNER_LOG_VOLUME_NAME,
@@ -55,7 +56,7 @@ import {
55
56
  runtimeContextEnv,
56
57
  runtimeStatePvcName,
57
58
  validateCloudConfig
58
- } from "./chunk-SUZ2ATT6.js";
59
+ } from "./chunk-FSW4TNHN.js";
59
60
  import {
60
61
  deepMerge,
61
62
  getPluginRegistry
@@ -10964,7 +10965,7 @@ function createOnboardCommand(container) {
10964
10965
  } else {
10965
10966
  const answer = await ask(` No ${configPath} found. Create one from template? [Y/n] `);
10966
10967
  if (!answer || answer.toLowerCase() !== "n") {
10967
- const { createInitCommand: createInitCommand2 } = await import("./init.command-6E24K4H3.js");
10968
+ const { createInitCommand: createInitCommand2 } = await import("./init.command-775GLXTC.js");
10968
10969
  const init = createInitCommand2(container);
10969
10970
  await init.parseAsync(["--quick"], { from: "user" });
10970
10971
  } else {
@@ -10981,7 +10982,7 @@ function createOnboardCommand(container) {
10981
10982
  }
10982
10983
  container.logger.success("Onboarding complete! Starting console...");
10983
10984
  console.log();
10984
- const { createConsoleCommand: createConsoleCommand2 } = await import("./dashboard.command-RV2NHDKW.js");
10985
+ const { createConsoleCommand: createConsoleCommand2 } = await import("./dashboard.command-H5DIGLUR.js");
10985
10986
  const console_ = createConsoleCommand2(container);
10986
10987
  await console_.parseAsync([], { from: "user" });
10987
10988
  });
@@ -13063,7 +13064,8 @@ function baseVolumeMounts(runtime) {
13063
13064
  { name: RUNNER_STATE_VOLUME_NAME, mountPath: runtime.container.statePath },
13064
13065
  { name: RUNNER_CONFIG_VOLUME_NAME, mountPath: RUNNER_CONFIG_MOUNT_PATH, readOnly: true },
13065
13066
  { name: RUNNER_LOG_VOLUME_NAME, mountPath: runtime.container.logPath },
13066
- { name: RUNNER_TMP_VOLUME_NAME, mountPath: "/tmp" }
13067
+ { name: RUNNER_TMP_VOLUME_NAME, mountPath: "/tmp" },
13068
+ { name: RUNNER_AGENTS_VOLUME_NAME, mountPath: "/workspace/.agents" }
13067
13069
  ];
13068
13070
  }
13069
13071
  function baseVolumes(configMapName) {
@@ -13071,7 +13073,8 @@ function baseVolumes(configMapName) {
13071
13073
  { name: RUNNER_STATE_VOLUME_NAME, emptyDir: {} },
13072
13074
  { name: RUNNER_CONFIG_VOLUME_NAME, configMap: { name: configMapName } },
13073
13075
  { name: RUNNER_LOG_VOLUME_NAME, emptyDir: {} },
13074
- { name: RUNNER_TMP_VOLUME_NAME, emptyDir: {} }
13076
+ { name: RUNNER_TMP_VOLUME_NAME, emptyDir: {} },
13077
+ { name: RUNNER_AGENTS_VOLUME_NAME, emptyDir: {} }
13075
13078
  ];
13076
13079
  }
13077
13080
  function buildAgentPodSpec(options) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createInitCommand
3
- } from "./chunk-R52J3PH2.js";
4
- import "./chunk-SUZ2ATT6.js";
3
+ } from "./chunk-2FWJSE6Z.js";
4
+ import "./chunk-FSW4TNHN.js";
5
5
  import "./chunk-JUPAE5IA.js";
6
6
  import "./chunk-R5U7XKVJ.js";
7
7
  export {
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createInitCommand
4
- } from "./chunk-KEPTCLUO.js";
5
- import "./chunk-QET4LT4J.js";
4
+ } from "./chunk-IXN3FU5J.js";
5
+ import "./chunk-ULOJLXQV.js";
6
6
  import "./chunk-6P2K6QZR.js";
7
7
  import "./chunk-AD3JTIU3.js";
8
8
  export {
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createServeCommand
4
- } from "./chunk-V2LU736V.js";
5
- import "./chunk-QET4LT4J.js";
4
+ } from "./chunk-XFJX4NWN.js";
5
+ import "./chunk-ULOJLXQV.js";
6
6
  import "./chunk-6P2K6QZR.js";
7
7
  import "./chunk-AD3JTIU3.js";
8
8
  export {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createServeCommand
3
- } from "./chunk-KKK5H7YX.js";
4
- import "./chunk-SUZ2ATT6.js";
3
+ } from "./chunk-I3NRNCDR.js";
4
+ import "./chunk-FSW4TNHN.js";
5
5
  import "./chunk-JUPAE5IA.js";
6
6
  import "./chunk-R5U7XKVJ.js";
7
7
  export {
@@ -0,0 +1,447 @@
1
+ ---
2
+ name: shadowob
3
+ description: "Use when live Shadow context or actions are needed: channel/DM history, pins, members, server/channel/workspace/shop/app/agent data, or sending/managing Shadow content via the shadowob CLI."
4
+ metadata:
5
+ {
6
+ "openclaw":
7
+ {
8
+ "emoji": "🏠",
9
+ "requires": { "bins": ["shadowob"] },
10
+ "primaryEnv": "SHADOWOB_TOKEN",
11
+ },
12
+ }
13
+ ---
14
+ allowed-tools: ["exec"]
15
+
16
+ # Shadow CLI
17
+
18
+ Use `shadowob` CLI to interact with Shadow servers.
19
+
20
+ Activate this skill when you need current Shadow context, such as recent channel or DM history,
21
+ pinned messages, member/server/channel state, workspace/shop/app/agent data, or when you need to
22
+ send or manage Shadow content. Prefer narrow `--json` reads before acting.
23
+
24
+ ## Quickstart
25
+
26
+ ```bash
27
+ # Login (one-time setup)
28
+ shadowob auth login --server-url https://shadowob.com --token <jwt>
29
+
30
+ # List servers
31
+ shadowob servers list --json
32
+
33
+ # Send a message
34
+ shadowob channels send <channel-id> --content "Hello" --json
35
+ ```
36
+
37
+ ## Authentication
38
+
39
+ Set token via:
40
+ 1. `shadowob auth login` (persistent, stored in `~/.shadowob/shadowob.config.json`)
41
+ 2. `--profile <name>` to use a specific profile
42
+ 3. `SHADOWOB_TOKEN` env var (used by SDK directly)
43
+
44
+ ### Profile Commands
45
+
46
+ ```bash
47
+ shadowob auth login --server-url <url> --token <token> --profile <name>
48
+ shadowob auth switch <profile>
49
+ shadowob auth list
50
+ shadowob auth whoami
51
+ shadowob auth logout --profile <name>
52
+ ```
53
+
54
+ ## Servers
55
+
56
+ ```bash
57
+ # List joined servers
58
+ shadowob servers list --json
59
+
60
+ # Get server details
61
+ shadowob servers get <server-id> --json
62
+
63
+ # Create server
64
+ shadowob servers create --name "My Server" --slug myserver --json
65
+
66
+ # Join/Leave
67
+ shadowob servers join <server-id> [--invite-code <code>]
68
+ shadowob servers leave <server-id>
69
+
70
+ # Members
71
+ shadowob servers members <server-id> --json
72
+
73
+ # Discover public servers
74
+ shadowob servers discover --json
75
+ ```
76
+
77
+ ## Channels
78
+
79
+ ```bash
80
+ # List channels
81
+ shadowob channels list --server-id <server-id> --json
82
+
83
+ # Get channel
84
+ shadowob channels get <channel-id> --json
85
+
86
+ # Create/Delete
87
+ shadowob channels create --server-id <id> --name <name> [--type text] --json
88
+ shadowob channels delete <channel-id>
89
+
90
+ # Messages
91
+ shadowob channels messages <channel-id> [--limit 50] [--cursor <cursor>] --json
92
+ shadowob channels send <channel-id> --content "text" [--reply-to <id>] [--thread-id <id>] --json
93
+ shadowob channels edit <message-id> --content "new text" --json
94
+ shadowob channels delete-message <message-id>
95
+
96
+ # Reactions
97
+ shadowob channels react <message-id> --emoji 👍
98
+ shadowob channels unreact <message-id> --emoji 👍
99
+
100
+ # Pins
101
+ shadowob channels pin <message-id> [--channel-id <id>]
102
+ shadowob channels unpin <message-id> [--channel-id <id>]
103
+ shadowob channels pinned <channel-id> --json
104
+ ```
105
+
106
+ ## Threads
107
+
108
+ ```bash
109
+ # List threads
110
+ shadowob threads list <channel-id> --json
111
+
112
+ # Get thread
113
+ shadowob threads get <thread-id> --json
114
+
115
+ # Create/Delete
116
+ shadowob threads create <channel-id> --name <name> --parent-message <id> --json
117
+ shadowob threads delete <thread-id>
118
+
119
+ # Messages
120
+ shadowob threads messages <thread-id> [--limit 50] --json
121
+ shadowob threads send <thread-id> --content "text" --json
122
+ ```
123
+
124
+ ## Direct Messages (DMs)
125
+
126
+ ```bash
127
+ # List DM channels
128
+ shadowob dms list --json
129
+
130
+ # Get DM channel
131
+ shadowob dms get <dm-channel-id> --json
132
+
133
+ # Create DM channel
134
+ shadowob dms create --user-id <user-id> --json
135
+
136
+ # Messages
137
+ shadowob dms messages <dm-channel-id> [--limit 50] --json
138
+ shadowob dms send <dm-channel-id> --content "text" --json
139
+
140
+ # Delete DM channel
141
+ shadowob dms delete <dm-channel-id>
142
+ ```
143
+
144
+ ## Agents
145
+
146
+ ```bash
147
+ # List agents
148
+ shadowob agents list --json
149
+
150
+ # Get agent
151
+ shadowob agents get <agent-id> --json
152
+
153
+ # Create/Update/Delete
154
+ shadowob agents create --name <name> [--display-name <name>] [--avatar-url <url>] --json
155
+ shadowob agents update <agent-id> [--name <name>] [--display-name <name>] --json
156
+ shadowob agents delete <agent-id>
157
+
158
+ # Control
159
+ shadowob agents start <agent-id>
160
+ shadowob agents stop <agent-id>
161
+
162
+ # Token
163
+ shadowob agents token <agent-id> --json
164
+
165
+ # Config
166
+ shadowob agents config <agent-id> --json
167
+ ```
168
+
169
+ ## Workspace
170
+
171
+ ```bash
172
+ # Workspace info
173
+ shadowob workspace get <server-id> --json
174
+ shadowob workspace tree <server-id> --json
175
+ shadowob workspace stats <server-id> --json
176
+
177
+ # Children
178
+ shadowob workspace children <server-id> [--parent-id <id>] --json
179
+
180
+ # Files
181
+ shadowob workspace files get <server-id> <file-id> --json
182
+ shadowob workspace files upload <server-id> --file <path> [--name <name>] [--parent-id <id>] --json
183
+ shadowob workspace files update <server-id> <file-id> [--name <name>] [--parent-id <id>] --json
184
+ shadowob workspace files delete <server-id> <file-id>
185
+ shadowob workspace files search <server-id> [--search-text <text>] [--ext <ext>] [--parent-id <id>] --json
186
+ # Note: files download is not yet implemented in CLI; download via contentRef URL instead.
187
+
188
+ # Folders
189
+ shadowob workspace folders create <server-id> --name <name> [--parent-id <id>] --json
190
+ shadowob workspace folders update <server-id> <folder-id> [--name <name>] [--parent-id <id>] --json
191
+ shadowob workspace folders delete <server-id> <folder-id>
192
+ ```
193
+
194
+ ### Workspace Node Metadata
195
+
196
+ Each workspace node has a `flags` JSONB field with optional metadata:
197
+
198
+ - **Access control**: `flags.access = { scope: "server" | "channel", serverId, channelId? }`. All nodes have at least `scope: "server"` + `serverId`. Channel-scoped nodes require channel membership for access.
199
+ - **Traceability**: `flags.source = "channel_message_attachment"` with `channelId` and `messageId` for files uploaded via channel messages, enabling reverse lookup to the originating message.
200
+ - **Path is server-computed**: `path` is derived from parent path + name, maintained server-side. Do not set path manually — it is auto-updated on rename/move.
201
+
202
+ ## Shop
203
+
204
+ ```bash
205
+ # Shop info
206
+ shadowob shop get <server-id> --json
207
+ shadowob shop get-by-id <shop-id> --json
208
+ shadowob shop me get --json
209
+
210
+ # Products
211
+ shadowob shop products list <server-id> [--status active] [--keyword <text>] [--limit <n>] --json
212
+ shadowob shop products list-by-shop <shop-id> [--status active] [--limit <n>] --json
213
+ shadowob shop products get <server-id> <product-id> --json
214
+ shadowob shop products context <product-id> --json
215
+ shadowob shop products purchase <shop-id> <product-id> --idempotency-key <unique-operation-id> --json
216
+
217
+ # Offers, deliverables, and shop assets
218
+ shadowob shop offers list <shop-id> --json
219
+ shadowob shop offers create <shop-id> --data '<offer-json>' --json
220
+ shadowob shop offers deliverables create <shop-id> <offer-id> --data '<deliverable-json>' --json
221
+ shadowob shop assets list <shop-id> --json
222
+ shadowob shop assets create <shop-id> --data '<asset-definition-json>' --json
223
+ shadowob shop entitlements list <shop-id> --json
224
+
225
+ # Cart
226
+ shadowob shop cart list <server-id> --json
227
+
228
+ # Orders
229
+ shadowob shop orders list <server-id> --json
230
+ shadowob shop orders get <server-id> <order-id> --json
231
+
232
+ # Wallet
233
+ shadowob shop wallet balance --json
234
+ ```
235
+
236
+ ## Commerce
237
+
238
+ ```bash
239
+ # Product and offer buyer context
240
+ shadowob commerce products context <product-id> --json
241
+ shadowob commerce offers preview <offer-id> --json
242
+ shadowob commerce offers purchase <offer-id> --idempotency-key <unique-operation-id> --json
243
+
244
+ # Chat commerce cards
245
+ shadowob commerce cards list --channel-id <channel-id> [--keyword <text>] --json
246
+ shadowob commerce cards purchase <message-id> <card-id> --idempotency-key <unique-operation-id> --json
247
+
248
+ # Purchases, delivery, protected files, and community assets
249
+ shadowob commerce entitlements list [--server-id <server-id>] --json
250
+ shadowob commerce entitlements get <entitlement-id> --json
251
+ shadowob commerce entitlements verify <entitlement-id> --json
252
+ shadowob commerce paid-files open <file-id> --json
253
+ shadowob commerce assets list --json
254
+ shadowob commerce assets consume <grant-id> --idempotency-key <unique-operation-id> --json
255
+
256
+ # Seller income and support actions
257
+ shadowob commerce settlements list --json
258
+ shadowob commerce settlements settle --json
259
+ shadowob commerce tips send --recipient-user-id <user-id> --amount <shrimp> [--message <text>] --json
260
+ shadowob commerce gifts send --recipient-user-id <user-id> --assets '<json-array>' --json
261
+ ```
262
+
263
+ ## Commerce Validation Notes
264
+
265
+ - Use the CLI for setup, inspection, and automation, but validate commerce user stories in the
266
+ browser before calling them complete.
267
+ - Do not add seed code to populate commerce surfaces. Create ordinary local/test records through
268
+ browser flows or explicit setup calls.
269
+ - When inspecting a commerce flow, preserve ids for the handoff: product, offer, order,
270
+ entitlement, shop, server, Buddy, and workspace file where applicable.
271
+ - External app entitlement automation must use Shadow OAuth commerce APIs and remain scoped to the
272
+ app's own `external_app` resource namespace.
273
+
274
+ ## Apps
275
+
276
+ ```bash
277
+ # Server App integrations
278
+ shadowob app list --server <server-id-or-slug> --json
279
+ shadowob app preview --server <server-id-or-slug> --manifest-url <manifest-url> --json
280
+ shadowob app discover --server <server-id-or-slug> --json
281
+ shadowob app inspect <app-key> --server <server-id-or-slug> --json
282
+ shadowob app skills <app-key> --server <server-id-or-slug>
283
+ shadowob app call <app-key> <command> --server <server-id-or-slug> --json-input '<raw-command-input-json>' --json
284
+ ```
285
+
286
+ For server App commands, use the `shadowob app` CLI path only. Do not use curl, fetch, raw HTTP
287
+ routes, or the JavaScript SDK to call server App commands. Pass the command input object directly
288
+ to `--json-input`, for example `{"title":"Example","priority":"high"}`; the CLI wraps the HTTP
289
+ request for you and binds Shadow OAuth identity, server membership, App grants, and command policy.
290
+ When a channel message mentions a server App, use the mentioned app key/server id directly.
291
+
292
+ ```bash
293
+ # Legacy workspace apps
294
+ shadowob apps list <server-id> --json
295
+
296
+ # Get app
297
+ shadowob apps get <app-id> --json
298
+
299
+ # Create/Update/Delete
300
+ shadowob apps create <server-id> --name <name> --type <url|workspace|static> [--source-url <url>] [--description <desc>] [--settings <json>] --json
301
+ shadowob apps update <app-id> [--name <name>] [--description <desc>] [--source-url <url>] [--settings <json>] --json
302
+ shadowob apps delete <app-id>
303
+
304
+ # Publish from workspace
305
+ shadowob apps publish <server-id> --folder-id <id> [--name <name>] [--description <desc>] --json
306
+
307
+ # Download source
308
+ shadowob apps download <app-id> [--output <path>]
309
+ ```
310
+
311
+ ## Notifications
312
+
313
+ ```bash
314
+ # List notifications
315
+ shadowob notifications list [--unread-only] [--limit <n>] --json
316
+
317
+ # Get/Read/Delete
318
+ shadowob notifications get <notification-id> --json
319
+ shadowob notifications mark-read <notification-id>
320
+ shadowob notifications mark-all-read
321
+ shadowob notifications delete <notification-id>
322
+
323
+ # Preferences
324
+ shadowob notifications preferences get --json
325
+ shadowob notifications preferences update [--email-enabled <bool>] [--push-enabled <bool>] [--mentions-only <bool>] --json
326
+ ```
327
+
328
+ ## Friends
329
+
330
+ ```bash
331
+ # List friends
332
+ shadowob friends list --json
333
+
334
+ # Friend requests
335
+ shadowob friends requests [--incoming] [--outgoing] --json
336
+ shadowob friends add <username> [--message <text>] --json
337
+ shadowob friends accept <request-id> --json
338
+ shadowob friends reject <request-id> --json
339
+
340
+ # Remove friend
341
+ shadowob friends remove <friendship-id> --json
342
+ ```
343
+
344
+ ## Invites
345
+
346
+ ```bash
347
+ # List your invite codes
348
+ shadowob invites list --json
349
+
350
+ # Create invite code
351
+ shadowob invites create [--max-uses <n>] [--expires-in <hours>] --json
352
+
353
+ # Deactivate/Delete invite
354
+ shadowob invites deactivate <invite-id>
355
+ shadowob invites delete <invite-id>
356
+ ```
357
+
358
+ ## OAuth
359
+
360
+ ```bash
361
+ # List OAuth apps
362
+ shadowob oauth list --json
363
+
364
+ # Create OAuth app
365
+ shadowob oauth create --name <name> [--description <desc>] [--redirect-uri <uri>] [--homepage <url>] --json
366
+
367
+ # Update/Delete OAuth app
368
+ shadowob oauth update <app-id> [--name <name>] [--description <desc>] [--redirect-uri <uri>] [--homepage <url>] --json
369
+ shadowob oauth delete <app-id>
370
+
371
+ # Reset client secret
372
+ shadowob oauth reset-secret <app-id> --json
373
+
374
+ # List authorized apps (user consents)
375
+ shadowob oauth consents --json
376
+
377
+ # Revoke consent for an app
378
+ shadowob oauth revoke <app-id>
379
+
380
+ # External app commerce entitlement checks use OAuth access tokens, not user JWTs
381
+ shadowob oauth commerce check --access-token <oauth-access-token> --resource-id <app-id>:premium --json
382
+ shadowob oauth commerce redeem --access-token <oauth-access-token> --resource-id <app-id>:premium --idempotency-key <provider-operation-id> --json
383
+ ```
384
+
385
+ ## Marketplace
386
+
387
+ ```bash
388
+ # Listings
389
+ shadowob marketplace listings list [--agent-id <id>] [--min-price <n>] [--max-price <n>] --json
390
+ shadowob marketplace listings get <listing-id> --json
391
+ shadowob marketplace listings create --agent-id <id> --price <n> [--description <text>] --json
392
+ shadowob marketplace listings update <listing-id> [--price <n>] [--description <text>] [--active <bool>] --json
393
+ shadowob marketplace listings delete <listing-id>
394
+
395
+ # Contracts
396
+ shadowob marketplace contracts list [--as-renter] [--as-owner] [--active-only] --json
397
+ shadowob marketplace contracts get <contract-id> --json
398
+ shadowob marketplace contracts create --listing-id <id> --hours <n> [--note <text>] --json
399
+ shadowob marketplace contracts cancel <contract-id>
400
+ shadowob marketplace contracts extend <contract-id> --hours <n> --json
401
+ ```
402
+
403
+ ## Media
404
+
405
+ ```bash
406
+ # Upload a file
407
+ shadowob media upload --file <path> [--server-id <id>] [--channel-id <id>] --json
408
+
409
+ # Download a file
410
+ shadowob media download <file-url> [--output <path>]
411
+ ```
412
+
413
+ ## Search
414
+
415
+ ```bash
416
+ # Search messages
417
+ shadowob search messages --query <text> [--server-id <id>] [--channel-id <id>] [--author-id <id>] [--after <date>] [--before <date>] [--has-attachments] [--limit <n>] --json
418
+ ```
419
+
420
+ ## Listen (Real-time Events)
421
+
422
+ ```bash
423
+ # Stream mode: listen until timeout or count
424
+ shadowob listen channel <channel-id> --mode stream [--timeout 60] [--count 10] --json
425
+
426
+ # Poll mode: fetch recent messages
427
+ shadowob listen channel <channel-id> --mode poll [--last 50] --json
428
+
429
+ # Filter events
430
+ shadowob listen channel <id> --event-type message:new,reaction:add --json
431
+
432
+ # DM events
433
+ shadowob listen dm <dm-channel-id> [--timeout 60] --json
434
+ ```
435
+
436
+ ## Output Format
437
+
438
+ - Default: human-readable list format
439
+ - `--json`: JSON output for programmatic use
440
+
441
+ ## Error Handling
442
+
443
+ Commands exit with code 1 on error. Use `--json` to get structured errors:
444
+
445
+ ```json
446
+ { "error": "message" }
447
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shadowob/cloud",
3
- "version": "1.1.6-dev.311",
3
+ "version": "1.1.6",
4
4
  "description": "shadowob-cloud — deploy AI agents to Kubernetes",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,8 +58,8 @@
58
58
  "yaml": "^2.8.4",
59
59
  "zod": "^3.25.76",
60
60
  "zustand": "^5.0.13",
61
- "@shadowob/sdk": "1.1.6-dev.311",
62
- "@shadowob/shared": "1.1.6-dev.311"
61
+ "@shadowob/sdk": "1.1.6",
62
+ "@shadowob/shared": "1.1.6"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@playwright/test": "^1.52.0",
@@ -90,6 +90,7 @@
90
90
  },
91
91
  "scripts": {
92
92
  "build": "tsup && rsbuild build",
93
+ "build:cli": "tsup",
93
94
  "dev": "tsup --watch",
94
95
  "dev:backend": "tsup --watch",
95
96
  "dev:frontend": "rsbuild dev",
@@ -98,7 +99,11 @@
98
99
  "console:preview": "rsbuild preview",
99
100
  "generate:plugin-library": "node --import tsx scripts/generate-plugin-library.ts",
100
101
  "generate:schema": "node --import tsx scripts/generate-schema.ts",
102
+ "copy:cli-skill": "node --import tsx scripts/copy-cli-skill.ts",
103
+ "prebuild:cli": "pnpm generate:plugin-library",
101
104
  "prebuild": "pnpm generate:plugin-library",
105
+ "postbuild:cli": "pnpm copy:cli-skill",
106
+ "postbuild": "pnpm copy:cli-skill",
102
107
  "predev": "pnpm generate:plugin-library",
103
108
  "predev:backend": "pnpm generate:plugin-library",
104
109
  "predev:frontend": "pnpm generate:plugin-library",
@@ -108,9 +113,9 @@
108
113
  "pretest": "pnpm generate:plugin-library",
109
114
  "test": "vitest run",
110
115
  "test:watch": "vitest",
111
- "pretest:e2e": "pnpm generate:plugin-library",
116
+ "pretest:e2e": "pnpm build:cli",
112
117
  "test:e2e": "vitest run --config vitest.e2e.config.ts",
113
- "pretest:e2e:cli": "pnpm generate:plugin-library",
118
+ "pretest:e2e:cli": "pnpm build:cli",
114
119
  "test:e2e:cli": "vitest run --config vitest.cli.config.ts",
115
120
  "pretest:e2e:console": "pnpm generate:plugin-library",
116
121
  "test:e2e:console": "playwright test",