@agentsky/sky 2.7.3 → 2.8.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.
|
@@ -19028,6 +19028,7 @@ var REASONING_EFFORTS = {
|
|
|
19028
19028
|
code_assistant: null,
|
|
19029
19029
|
docker_cagent: null,
|
|
19030
19030
|
kiro: null,
|
|
19031
|
+
muse_code: null,
|
|
19031
19032
|
openhands: null,
|
|
19032
19033
|
hermes: ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"],
|
|
19033
19034
|
claude_code: ["low", "medium", "high", "xhigh", "max"],
|
|
@@ -19339,6 +19340,13 @@ var ACP_AGENTS = {
|
|
|
19339
19340
|
"version": "2.22.0",
|
|
19340
19341
|
"website": "https://kiro.dev/docs/cli/acp/"
|
|
19341
19342
|
},
|
|
19343
|
+
"muse_code": {
|
|
19344
|
+
"registryId": "muse-code",
|
|
19345
|
+
"label": "Muse Code",
|
|
19346
|
+
"description": "Meta's coding agent and CLI",
|
|
19347
|
+
"version": "1.4.3",
|
|
19348
|
+
"website": "https://dev.meta.ai/docs/muse-code/"
|
|
19349
|
+
},
|
|
19342
19350
|
"openhands": {
|
|
19343
19351
|
"registryId": "openhands",
|
|
19344
19352
|
"label": "OpenHands",
|
|
@@ -19388,7 +19396,8 @@ var ACP_AGENT_TYPES = [
|
|
|
19388
19396
|
"code_assistant",
|
|
19389
19397
|
"docker_cagent",
|
|
19390
19398
|
"kiro",
|
|
19391
|
-
"openhands"
|
|
19399
|
+
"openhands",
|
|
19400
|
+
"muse_code"
|
|
19392
19401
|
];
|
|
19393
19402
|
function isAcpAgentType(value) {
|
|
19394
19403
|
return Object.hasOwn(ACP_AGENTS, value);
|
|
@@ -20891,6 +20900,35 @@ var ACP_ACCOUNT_PROFILES = {
|
|
|
20891
20900
|
"https://kiro.dev/docs/getting-started/authentication/"
|
|
20892
20901
|
]
|
|
20893
20902
|
},
|
|
20903
|
+
"muse_code": {
|
|
20904
|
+
"name": "Muse Code",
|
|
20905
|
+
"version": "1.4.3",
|
|
20906
|
+
"status": "documented",
|
|
20907
|
+
"setupModes": [
|
|
20908
|
+
{
|
|
20909
|
+
"id": "api_key",
|
|
20910
|
+
"label": "API key",
|
|
20911
|
+
"fields": [
|
|
20912
|
+
{
|
|
20913
|
+
"key": "META_API_KEY",
|
|
20914
|
+
"label": "Meta API key",
|
|
20915
|
+
"kind": "secret",
|
|
20916
|
+
"required": true,
|
|
20917
|
+
"source": "https://dev.meta.ai/docs/muse-code/"
|
|
20918
|
+
}
|
|
20919
|
+
],
|
|
20920
|
+
"source": "https://dev.meta.ai/docs/muse-code/"
|
|
20921
|
+
}
|
|
20922
|
+
],
|
|
20923
|
+
"files": [],
|
|
20924
|
+
"notes": [
|
|
20925
|
+
"Muse Code runs through a community ACP adapter in front of Meta's own host binary. An authenticated turn has not been exercised."
|
|
20926
|
+
],
|
|
20927
|
+
"sources": [
|
|
20928
|
+
"https://dev.meta.ai/docs/muse-code/",
|
|
20929
|
+
"https://github.com/bex-co/muse-code-acp"
|
|
20930
|
+
]
|
|
20931
|
+
},
|
|
20894
20932
|
"openhands": {
|
|
20895
20933
|
"name": "OpenHands",
|
|
20896
20934
|
"version": "1.16.0",
|
|
@@ -21935,6 +21973,7 @@ var GATEWAY_CAPABILITY_IDS = [
|
|
|
21935
21973
|
"wan.image"
|
|
21936
21974
|
];
|
|
21937
21975
|
var CAPABILITY_IDS = [...LEGACY_CAPABILITY_IDS, ...GATEWAY_CAPABILITY_IDS];
|
|
21976
|
+
var PLATFORM_CAPABILITY_IDS = ["platform.orchestration"];
|
|
21938
21977
|
var allowedLlms = {
|
|
21939
21978
|
jev: ["typesafe/jev-1.13"],
|
|
21940
21979
|
agoragentic_acp: ["harness-default"],
|
|
@@ -21977,6 +22016,7 @@ var allowedLlms = {
|
|
|
21977
22016
|
code_assistant: [...ACP_PLATFORM_MODELS.code_assistant, "harness-default"],
|
|
21978
22017
|
docker_cagent: [...ACP_PLATFORM_MODELS.docker_cagent, "harness-default"],
|
|
21979
22018
|
kiro: ["harness-default"],
|
|
22019
|
+
muse_code: ["harness-default"],
|
|
21980
22020
|
openhands: [...ACP_PLATFORM_MODELS.openhands, "harness-default"],
|
|
21981
22021
|
hermes: [
|
|
21982
22022
|
"deepseek-v4-pro",
|
|
@@ -22177,19 +22217,22 @@ function modelSubscriptionProviderFor(agentType, llm) {
|
|
|
22177
22217
|
if (agentType === "codex" && CHATGPT_PLAN_MODELS.has(llm)) return "openai";
|
|
22178
22218
|
if (agentType === "cursor" && llm === "harness-default") return "cursor";
|
|
22179
22219
|
if (agentType === "grok_build" && llm === "harness-default") return "xai";
|
|
22220
|
+
if (agentType === "muse_code" && llm === "harness-default") return "meta";
|
|
22180
22221
|
return null;
|
|
22181
22222
|
}
|
|
22182
22223
|
var MODEL_SUBSCRIPTION_PROVIDER_NAME = {
|
|
22183
22224
|
anthropic: "Claude",
|
|
22184
22225
|
openai: "ChatGPT",
|
|
22185
22226
|
cursor: "Cursor",
|
|
22186
|
-
xai: "Grok"
|
|
22227
|
+
xai: "Grok",
|
|
22228
|
+
meta: "Muse"
|
|
22187
22229
|
};
|
|
22188
22230
|
var MODEL_SUBSCRIPTION_PLAN_PHRASE = {
|
|
22189
22231
|
anthropic: "Claude subscription",
|
|
22190
22232
|
openai: "ChatGPT plan",
|
|
22191
22233
|
cursor: "Cursor plan",
|
|
22192
|
-
xai: "Grok subscription"
|
|
22234
|
+
xai: "Grok subscription",
|
|
22235
|
+
meta: "Muse subscription"
|
|
22193
22236
|
};
|
|
22194
22237
|
var AGENT_TYPE_META = {
|
|
22195
22238
|
...Object.fromEntries(ACP_AGENT_TYPES.map((agentType) => [agentType, {
|
|
@@ -22362,8 +22405,10 @@ var spendCapPolicyConfigSchema = external_exports.object({
|
|
|
22362
22405
|
});
|
|
22363
22406
|
var callCountPolicyConfigSchema = external_exports.object({ limitPerSession: external_exports.number().int().min(1).max(1e5) }).strict();
|
|
22364
22407
|
var capabilityPolicyConfigSchema = external_exports.record(external_exports.string(), external_exports.enum(POLICY_ACTIONS)).superRefine((obj, ctx) => {
|
|
22365
|
-
for (const k of Object.
|
|
22366
|
-
if (
|
|
22408
|
+
for (const [k, action] of Object.entries(obj)) {
|
|
22409
|
+
if (PLATFORM_CAPABILITY_IDS.includes(k)) {
|
|
22410
|
+
if (action === "ask") ctx.addIssue({ code: "custom", message: `${k} accepts allow or deny`, path: [k] });
|
|
22411
|
+
} else if (!CAPABILITY_IDS.includes(k)) {
|
|
22367
22412
|
ctx.addIssue({ code: "custom", message: `unknown capability id: ${k}`, path: [k] });
|
|
22368
22413
|
}
|
|
22369
22414
|
}
|
package/dist/index.js
CHANGED
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
skillRefSchema,
|
|
17
17
|
splitMcpServers,
|
|
18
18
|
supersededBy
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-WFTZR5YO.js";
|
|
20
20
|
|
|
21
21
|
// src/index.ts
|
|
22
|
-
import { existsSync as existsSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
22
|
+
import { existsSync as existsSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
|
|
23
23
|
import { basename as basename3, resolve as resolve4 } from "path";
|
|
24
24
|
import { createInterface as createInterface4 } from "readline";
|
|
25
25
|
import { Command } from "commander";
|
|
@@ -64,7 +64,7 @@ function currentUniverse() {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// src/version.ts
|
|
67
|
-
var CLI_VERSION = "2.
|
|
67
|
+
var CLI_VERSION = "2.8.0";
|
|
68
68
|
var USER_AGENT = `sky-cli/${CLI_VERSION} (${process.platform}; node/${process.versions.node})`;
|
|
69
69
|
|
|
70
70
|
// src/api.ts
|
|
@@ -148,6 +148,24 @@ async function downloadFile(fileId) {
|
|
|
148
148
|
if (!res.ok) await parseError(res);
|
|
149
149
|
return { bytes: new Uint8Array(await res.arrayBuffer()), mediaType: res.headers.get("content-type") ?? "application/octet-stream" };
|
|
150
150
|
}
|
|
151
|
+
async function apiBytes(method, path, body) {
|
|
152
|
+
const res = await fetch(`${apiBase()}${path}`, {
|
|
153
|
+
method,
|
|
154
|
+
headers: {
|
|
155
|
+
"user-agent": USER_AGENT,
|
|
156
|
+
...authHeaders(),
|
|
157
|
+
...body ? { "content-type": body.mediaType } : {}
|
|
158
|
+
},
|
|
159
|
+
body: body ? new Uint8Array(body.bytes) : void 0
|
|
160
|
+
});
|
|
161
|
+
if (!res.ok) await parseError(res);
|
|
162
|
+
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
163
|
+
return {
|
|
164
|
+
bytes,
|
|
165
|
+
mediaType: res.headers.get("content-type") ?? "application/octet-stream",
|
|
166
|
+
json: () => JSON.parse(new TextDecoder().decode(bytes))
|
|
167
|
+
};
|
|
168
|
+
}
|
|
151
169
|
async function resolveSessionRef(ref) {
|
|
152
170
|
if (ref.startsWith("sess-")) return ref;
|
|
153
171
|
const { agent: agent2 } = await api(
|
|
@@ -167,7 +185,7 @@ async function resolveSessionRef(ref) {
|
|
|
167
185
|
return agent2.defaultSessionId;
|
|
168
186
|
}
|
|
169
187
|
async function* streamEvents(sessionId, signal) {
|
|
170
|
-
const { parseSseStream } = await import("./src-
|
|
188
|
+
const { parseSseStream } = await import("./src-2DLGPJB6.js");
|
|
171
189
|
const res = await fetch(
|
|
172
190
|
`${apiBase()}/sessions/${encodeURIComponent(sessionId)}/stream`,
|
|
173
191
|
{
|
|
@@ -1977,6 +1995,144 @@ async function importToWorkspace(key, held, skills, instructions, emit) {
|
|
|
1977
1995
|
if (!finished.ok) emit({ type: "error", code: finished.code, message: finished.message });
|
|
1978
1996
|
}
|
|
1979
1997
|
|
|
1998
|
+
// src/task-files.ts
|
|
1999
|
+
function encodePath(path) {
|
|
2000
|
+
return path.replace(/^\/+/, "").split("/").map(encodeURIComponent).join("/");
|
|
2001
|
+
}
|
|
2002
|
+
var filesPath = (task2) => `/tasks/${encodeURIComponent(task2)}/files`;
|
|
2003
|
+
async function listTaskFiles(task2) {
|
|
2004
|
+
return (await api("GET", filesPath(task2))).files;
|
|
2005
|
+
}
|
|
2006
|
+
async function readTaskFile(task2, path) {
|
|
2007
|
+
return (await apiBytes("GET", `${filesPath(task2)}/${encodePath(path)}`)).bytes;
|
|
2008
|
+
}
|
|
2009
|
+
async function writeTaskFile(task2, path, bytes, mediaType) {
|
|
2010
|
+
return (await apiBytes("PUT", `${filesPath(task2)}/${encodePath(path)}`, { bytes, mediaType })).json();
|
|
2011
|
+
}
|
|
2012
|
+
async function deleteTaskFile(task2, path) {
|
|
2013
|
+
await api("DELETE", `${filesPath(task2)}/${encodePath(path)}`);
|
|
2014
|
+
}
|
|
2015
|
+
async function listArtifacts(task2) {
|
|
2016
|
+
const query = task2 ? `?task_id=${encodeURIComponent(task2)}` : "";
|
|
2017
|
+
return (await api("GET", `/artifacts${query}`)).artifacts;
|
|
2018
|
+
}
|
|
2019
|
+
function publishBody(task2, options) {
|
|
2020
|
+
return { task_id: task2, name: options.name, paths: options.path, ...options.entry ? { entry: options.entry } : {} };
|
|
2021
|
+
}
|
|
2022
|
+
async function publishArtifact(task2, options) {
|
|
2023
|
+
return (await api("POST", "/artifacts", publishBody(task2, options))).artifact;
|
|
2024
|
+
}
|
|
2025
|
+
async function readArtifactFile(id, path) {
|
|
2026
|
+
return (await apiBytes("GET", `/artifacts/${encodeURIComponent(id)}/files/${encodePath(path)}`)).bytes;
|
|
2027
|
+
}
|
|
2028
|
+
async function shareArtifact(id, enabled) {
|
|
2029
|
+
return (await api("POST", `/artifacts/${encodeURIComponent(id)}/share`, { enabled })).share_url;
|
|
2030
|
+
}
|
|
2031
|
+
async function deleteArtifact(id) {
|
|
2032
|
+
await api("DELETE", `/artifacts/${encodeURIComponent(id)}`);
|
|
2033
|
+
}
|
|
2034
|
+
function renderTaskFile(file) {
|
|
2035
|
+
return `${file.path} ${file.size_bytes} bytes ${file.updated_at}${file.updated_by_session ? ` by ${file.updated_by_session}` : ""}`;
|
|
2036
|
+
}
|
|
2037
|
+
function renderArtifact(artifact2) {
|
|
2038
|
+
const files2 = `${artifact2.files.length} ${artifact2.files.length === 1 ? "file" : "files"}`;
|
|
2039
|
+
return `${artifact2.id} ${artifact2.name} v${artifact2.version} ${files2} entry ${artifact2.entry}${artifact2.share_url ? ` shared ${artifact2.share_url}` : ""}`;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
// src/workspace.ts
|
|
2043
|
+
var KINDS = ["TOOL_CALL", "SPEND_CAP", "CALL_COUNT", "CAPABILITY"];
|
|
2044
|
+
async function workspaceSlug(explicit) {
|
|
2045
|
+
if (explicit) return explicit;
|
|
2046
|
+
const current = currentUniverse();
|
|
2047
|
+
if (current) return current;
|
|
2048
|
+
return (await api("GET", "/whoami")).universe.slug;
|
|
2049
|
+
}
|
|
2050
|
+
var workspacePath = (slug) => `/universes/${encodeURIComponent(slug)}`;
|
|
2051
|
+
async function listMembers(slug) {
|
|
2052
|
+
return api("GET", `${workspacePath(slug)}/members`);
|
|
2053
|
+
}
|
|
2054
|
+
function findMember(members, ref) {
|
|
2055
|
+
const needle = ref.toLowerCase();
|
|
2056
|
+
const found = members.find((m) => m.user_id === ref || m.email?.toLowerCase() === needle);
|
|
2057
|
+
if (!found) throw new ApiError(404, "not_found", `no member ${ref} in this workspace`);
|
|
2058
|
+
return found;
|
|
2059
|
+
}
|
|
2060
|
+
function inviteBody(emails, options) {
|
|
2061
|
+
if (options.role && options.role !== "admin" && options.role !== "member") {
|
|
2062
|
+
throw new ApiError(400, "invalid_request", "--role is admin or member");
|
|
2063
|
+
}
|
|
2064
|
+
return {
|
|
2065
|
+
emails,
|
|
2066
|
+
...options.role ? { role: options.role } : {},
|
|
2067
|
+
...options.sendEmail ? { send_email: true } : {}
|
|
2068
|
+
};
|
|
2069
|
+
}
|
|
2070
|
+
async function invite(slug, emails, options) {
|
|
2071
|
+
return api("POST", `${workspacePath(slug)}/invites`, inviteBody(emails, options));
|
|
2072
|
+
}
|
|
2073
|
+
async function withdrawInvite(slug, inviteId) {
|
|
2074
|
+
await api("DELETE", `${workspacePath(slug)}/invites/${encodeURIComponent(inviteId)}`);
|
|
2075
|
+
}
|
|
2076
|
+
async function setRole(slug, memberRef, role) {
|
|
2077
|
+
if (role !== "admin" && role !== "member") throw new ApiError(400, "invalid_request", "a role is admin or member");
|
|
2078
|
+
const member = findMember((await listMembers(slug)).members, memberRef);
|
|
2079
|
+
await api("PATCH", `${workspacePath(slug)}/members/${encodeURIComponent(member.user_id)}`, { role });
|
|
2080
|
+
return member;
|
|
2081
|
+
}
|
|
2082
|
+
async function removeMember(slug, memberRef) {
|
|
2083
|
+
const member = findMember((await listMembers(slug)).members, memberRef);
|
|
2084
|
+
await api("DELETE", `${workspacePath(slug)}/members/${encodeURIComponent(member.user_id)}`);
|
|
2085
|
+
return member;
|
|
2086
|
+
}
|
|
2087
|
+
async function joinWorkspace(token) {
|
|
2088
|
+
return (await api("POST", `/invites/${encodeURIComponent(token)}`)).workspace;
|
|
2089
|
+
}
|
|
2090
|
+
function renderMembers(page) {
|
|
2091
|
+
const lines = page.members.map((m) => `${m.role.padEnd(6)} ${m.email ?? m.user_id}${m.name ? ` (${m.name})` : ""} ${m.user_id}`);
|
|
2092
|
+
for (const i of page.invites) lines.push(`invited ${i.email} as ${i.role} by ${i.invited_by} until ${i.expires_at.slice(0, 10)} ${i.id}`);
|
|
2093
|
+
return lines;
|
|
2094
|
+
}
|
|
2095
|
+
function policyRuleBody(options) {
|
|
2096
|
+
const kind = options.kind.toUpperCase().replace(/-/g, "_");
|
|
2097
|
+
if (!KINDS.includes(kind)) throw new ApiError(400, "invalid_request", `--kind is one of ${KINDS.join(", ")}`);
|
|
2098
|
+
let config;
|
|
2099
|
+
try {
|
|
2100
|
+
config = JSON.parse(options.config);
|
|
2101
|
+
} catch {
|
|
2102
|
+
throw new ApiError(400, "invalid_request", "--config must be a JSON object");
|
|
2103
|
+
}
|
|
2104
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) {
|
|
2105
|
+
throw new ApiError(400, "invalid_request", "--config must be a JSON object");
|
|
2106
|
+
}
|
|
2107
|
+
const position = options.position === void 0 ? void 0 : Number(options.position);
|
|
2108
|
+
if (position !== void 0 && !Number.isInteger(position)) throw new ApiError(400, "invalid_request", "--position is a whole number");
|
|
2109
|
+
return {
|
|
2110
|
+
name: options.name,
|
|
2111
|
+
kind,
|
|
2112
|
+
config,
|
|
2113
|
+
...position !== void 0 ? { position } : {},
|
|
2114
|
+
...options.disabled ? { enabled: false } : {}
|
|
2115
|
+
};
|
|
2116
|
+
}
|
|
2117
|
+
var policiesPath = (scope) => "session" in scope ? `/sessions/${encodeURIComponent(scope.session)}/policies` : `${workspacePath(scope.slug)}/policies`;
|
|
2118
|
+
async function listPolicies(scope, effective = false) {
|
|
2119
|
+
if (effective && "session" in scope) return api("GET", `/sessions/${encodeURIComponent(scope.session)}/effective-policy`);
|
|
2120
|
+
return api("GET", policiesPath(scope));
|
|
2121
|
+
}
|
|
2122
|
+
async function addPolicy(scope, options) {
|
|
2123
|
+
return (await api("POST", policiesPath(scope), policyRuleBody(options))).rule;
|
|
2124
|
+
}
|
|
2125
|
+
async function setPolicyEnabled(scope, ruleId, enabled) {
|
|
2126
|
+
return (await api("PATCH", `${policiesPath(scope)}/${encodeURIComponent(ruleId)}`, { enabled })).rule;
|
|
2127
|
+
}
|
|
2128
|
+
async function removePolicy(scope, ruleId) {
|
|
2129
|
+
await api("DELETE", `${policiesPath(scope)}/${encodeURIComponent(ruleId)}`);
|
|
2130
|
+
}
|
|
2131
|
+
function renderPolicy(rule) {
|
|
2132
|
+
const state = rule.enabled ? "on " : "off";
|
|
2133
|
+
return `${state} ${rule.layer.padEnd(9)} ${rule.kind.padEnd(10)} ${rule.name} ${JSON.stringify(rule.config)} ${rule.id}`;
|
|
2134
|
+
}
|
|
2135
|
+
|
|
1980
2136
|
// src/index.ts
|
|
1981
2137
|
function printModelBilling(session2) {
|
|
1982
2138
|
if (session2.modelBilling !== "account") return;
|
|
@@ -2055,6 +2211,84 @@ universe.command("show").action(
|
|
|
2055
2211
|
}
|
|
2056
2212
|
})
|
|
2057
2213
|
);
|
|
2214
|
+
universe.command("members [slug]").description("who is in the workspace, and who is invited (owners and admins)").action(
|
|
2215
|
+
run(async (slug) => {
|
|
2216
|
+
for (const line of renderMembers(await listMembers(await workspaceSlug(slug)))) console.log(line);
|
|
2217
|
+
})
|
|
2218
|
+
);
|
|
2219
|
+
universe.command("invite <emails...>").description("invite people by email; prints each person's join link token").option("--role <role>", "admin | member (default member; admin needs the owner)").option("--send-email", "also email each invitation").option("--universe <slug>", "the workspace (default: the current one)").action(
|
|
2220
|
+
run(async (emails, opts) => {
|
|
2221
|
+
const result = await invite(await workspaceSlug(opts.universe), emails, opts);
|
|
2222
|
+
for (const i of result.invites) console.log(`invited ${i.email} as ${i.role} ${i.id}`);
|
|
2223
|
+
for (const link of result.links) console.log(` ${link.email} joins with: sky universe join ${link.token}`);
|
|
2224
|
+
if (!result.invites.length) console.log("nobody new to invite \u2014 everyone listed is already a member");
|
|
2225
|
+
})
|
|
2226
|
+
);
|
|
2227
|
+
universe.command("uninvite <inviteId>").description("withdraw an invitation that has not been taken up").option("--universe <slug>", "the workspace (default: the current one)").action(
|
|
2228
|
+
run(async (inviteId, opts) => {
|
|
2229
|
+
await withdrawInvite(await workspaceSlug(opts.universe), inviteId);
|
|
2230
|
+
console.log(`Withdrew ${inviteId}`);
|
|
2231
|
+
})
|
|
2232
|
+
);
|
|
2233
|
+
universe.command("role <member> <role>").description("make a member (user id or email) an admin or a member (owner only)").option("--universe <slug>", "the workspace (default: the current one)").action(
|
|
2234
|
+
run(async (memberRef, role, opts) => {
|
|
2235
|
+
const member = await setRole(await workspaceSlug(opts.universe), memberRef, role);
|
|
2236
|
+
console.log(`${member.email ?? member.user_id} is now ${role}`);
|
|
2237
|
+
})
|
|
2238
|
+
);
|
|
2239
|
+
universe.command("remove <member>").description("remove a member (user id or email) from the workspace (owner only)").option("--universe <slug>", "the workspace (default: the current one)").action(
|
|
2240
|
+
run(async (memberRef, opts) => {
|
|
2241
|
+
const member = await removeMember(await workspaceSlug(opts.universe), memberRef);
|
|
2242
|
+
console.log(`Removed ${member.email ?? member.user_id}`);
|
|
2243
|
+
})
|
|
2244
|
+
);
|
|
2245
|
+
universe.command("join <token>").description("accept an invitation sent to your verified email").action(
|
|
2246
|
+
run(async (token) => {
|
|
2247
|
+
const workspace = await joinWorkspace(token);
|
|
2248
|
+
console.log(`Joined ${workspace.slug} (${workspace.name}) \u2014 sky universe switch ${workspace.slug}`);
|
|
2249
|
+
})
|
|
2250
|
+
);
|
|
2251
|
+
var policy = program.command("policy").description("policy rules: tool calls, spend caps, call counts, capabilities");
|
|
2252
|
+
async function policyScope(opts) {
|
|
2253
|
+
return opts.session ? { session: await resolveSessionRef(opts.session) } : { slug: await workspaceSlug(opts.universe) };
|
|
2254
|
+
}
|
|
2255
|
+
var scopeOptions = (command) => command.option("--session <ref>", "one session's rules instead of the workspace's").option("--universe <slug>", "the workspace (default: the current one)");
|
|
2256
|
+
scopeOptions(
|
|
2257
|
+
policy.command("list").description("the workspace's rules, or one session's; --effective merges every layer").option("--effective", "with --session: every rule the session runs under")
|
|
2258
|
+
).action(
|
|
2259
|
+
run(async (opts) => {
|
|
2260
|
+
const { rules, note } = await listPolicies(await policyScope(opts), opts.effective);
|
|
2261
|
+
if (!rules.length) console.log("no policy rules");
|
|
2262
|
+
for (const rule of rules) console.log(renderPolicy(rule));
|
|
2263
|
+
if (note) console.log(note);
|
|
2264
|
+
})
|
|
2265
|
+
);
|
|
2266
|
+
scopeOptions(
|
|
2267
|
+
policy.command("add").description("add a rule (workspace owner, or the session's owner with --session)").requiredOption("--name <name>", "what the rule is for").requiredOption("--kind <kind>", "TOOL_CALL | SPEND_CAP | CALL_COUNT | CAPABILITY").requiredOption(
|
|
2268
|
+
"--config <json>",
|
|
2269
|
+
`e.g. '{"action":"deny","matcher":"Bash","commandPatterns":["rm -rf *"]}', '{"hardCapUsdMicros":5000000}', '{"limitPerSession":200}', '{"platform.orchestration":"deny"}'`
|
|
2270
|
+
).option("--position <n>", "evaluation order, lowest first (default 0)").option("--disabled", "create it switched off")
|
|
2271
|
+
).action(
|
|
2272
|
+
run(async (opts) => {
|
|
2273
|
+
console.log(renderPolicy(await addPolicy(await policyScope(opts), opts)));
|
|
2274
|
+
})
|
|
2275
|
+
);
|
|
2276
|
+
for (const [verb, enabled, description] of [
|
|
2277
|
+
["enable", true, "switch a rule on"],
|
|
2278
|
+
["disable", false, "switch a rule off (kept, so it can be switched on again)"]
|
|
2279
|
+
]) {
|
|
2280
|
+
scopeOptions(policy.command(`${verb} <ruleId>`).description(description)).action(
|
|
2281
|
+
run(async (ruleId, opts) => {
|
|
2282
|
+
console.log(renderPolicy(await setPolicyEnabled(await policyScope(opts), ruleId, enabled)));
|
|
2283
|
+
})
|
|
2284
|
+
);
|
|
2285
|
+
}
|
|
2286
|
+
scopeOptions(policy.command("rm <ruleId>").description("delete a rule")).action(
|
|
2287
|
+
run(async (ruleId, opts) => {
|
|
2288
|
+
await removePolicy(await policyScope(opts), ruleId);
|
|
2289
|
+
console.log(`Deleted ${ruleId}`);
|
|
2290
|
+
})
|
|
2291
|
+
);
|
|
2058
2292
|
var agent = program.command("agent").description("agent specs: create, inspect, talk (via the default session)");
|
|
2059
2293
|
agent.command("create").description("create an agent spec \u2014 no runtime; `sky session create` starts one").option("--type <type>", "hermes | claude_code | codex | openclaw | pi | dsh | kimi_code | opencode").option("--llm <llm>", "model id (defaults per type)").option(
|
|
2060
2294
|
"--reasoning-effort <level>",
|
|
@@ -2700,6 +2934,69 @@ files.command("download <id>").description("download a session file's bytes").re
|
|
|
2700
2934
|
console.log(`Wrote ${bytes.length} bytes to ${opts.out}`);
|
|
2701
2935
|
})
|
|
2702
2936
|
);
|
|
2937
|
+
var task = program.command("task").description("a task's shared files (the task is its first session's id)");
|
|
2938
|
+
task.command("files <task>").description("list the task's current files").action(
|
|
2939
|
+
run(async (taskId) => {
|
|
2940
|
+
const list = await listTaskFiles(taskId);
|
|
2941
|
+
if (!list.length) console.log("no files");
|
|
2942
|
+
for (const file of list) console.log(renderTaskFile(file));
|
|
2943
|
+
})
|
|
2944
|
+
);
|
|
2945
|
+
task.command("get <task> <path>").description("read one task file; prints it, or writes it with -o").option("-o, --out <path>", "where to write the bytes").action(
|
|
2946
|
+
run(async (taskId, path, opts) => {
|
|
2947
|
+
const bytes = await readTaskFile(taskId, path);
|
|
2948
|
+
if (opts.out) {
|
|
2949
|
+
writeFileSync6(opts.out, bytes);
|
|
2950
|
+
console.log(`Wrote ${bytes.length} bytes to ${opts.out}`);
|
|
2951
|
+
} else process.stdout.write(bytes);
|
|
2952
|
+
})
|
|
2953
|
+
);
|
|
2954
|
+
task.command("put <task> <path> <local>").description("write a local file to <path> in the task's files (every session of the task sees it)").action(
|
|
2955
|
+
run(async (taskId, path, local) => {
|
|
2956
|
+
const { file, conflict } = await writeTaskFile(taskId, path, readFileSync10(local), mediaTypeFor(local));
|
|
2957
|
+
console.log(`${renderTaskFile(file)}${conflict ? " (replaced a version you had not seen)" : ""}`);
|
|
2958
|
+
})
|
|
2959
|
+
);
|
|
2960
|
+
task.command("rm <task> <path>").description("remove a path from the task's files (its history is kept)").action(
|
|
2961
|
+
run(async (taskId, path) => {
|
|
2962
|
+
await deleteTaskFile(taskId, path);
|
|
2963
|
+
console.log(`Removed ${path}`);
|
|
2964
|
+
})
|
|
2965
|
+
);
|
|
2966
|
+
var artifact = program.command("artifact").description("artifacts: publish a task's files as a named, shareable result");
|
|
2967
|
+
artifact.command("list").description("the workspace's artifacts, or one task's with --task").option("--task <task>", "only this task's artifacts").action(
|
|
2968
|
+
run(async (opts) => {
|
|
2969
|
+
const list = await listArtifacts(opts.task);
|
|
2970
|
+
if (!list.length) console.log("no artifacts");
|
|
2971
|
+
for (const a of list) console.log(renderArtifact(a));
|
|
2972
|
+
})
|
|
2973
|
+
);
|
|
2974
|
+
artifact.command("publish <task>").description("publish paths from the task's files as a new version of the named artifact").requiredOption("--name <name>", "the artifact's name; publishing the same name again adds a version").requiredOption("--path <path...>", "task file paths to include").option("--entry <path>", "the file a viewer opens first (default: the first path)").action(
|
|
2975
|
+
run(async (taskId, opts) => {
|
|
2976
|
+
console.log(renderArtifact(await publishArtifact(taskId, opts)));
|
|
2977
|
+
})
|
|
2978
|
+
);
|
|
2979
|
+
artifact.command("get <id> <path>").description("read one file of an artifact; prints it, or writes it with -o").option("-o, --out <path>", "where to write the bytes").action(
|
|
2980
|
+
run(async (id, path, opts) => {
|
|
2981
|
+
const bytes = await readArtifactFile(id, path);
|
|
2982
|
+
if (opts.out) {
|
|
2983
|
+
writeFileSync6(opts.out, bytes);
|
|
2984
|
+
console.log(`Wrote ${bytes.length} bytes to ${opts.out}`);
|
|
2985
|
+
} else process.stdout.write(bytes);
|
|
2986
|
+
})
|
|
2987
|
+
);
|
|
2988
|
+
artifact.command("share <id>").description("turn on a public link anyone can open; --off turns it off (the old link stops working)").option("--off", "stop sharing").action(
|
|
2989
|
+
run(async (id, opts) => {
|
|
2990
|
+
const url = await shareArtifact(id, !opts.off);
|
|
2991
|
+
console.log(url ?? `Stopped sharing ${id}`);
|
|
2992
|
+
})
|
|
2993
|
+
);
|
|
2994
|
+
artifact.command("rm <id>").description("delete an artifact").action(
|
|
2995
|
+
run(async (id) => {
|
|
2996
|
+
await deleteArtifact(id);
|
|
2997
|
+
console.log(`Deleted ${id}`);
|
|
2998
|
+
})
|
|
2999
|
+
);
|
|
2703
3000
|
function routineLine(r) {
|
|
2704
3001
|
const target = r.target.type === "session" ? `\u2192 ${r.target.session_id}` : `+ ${r.target.agent}`;
|
|
2705
3002
|
const cron = r.schedule ? `${r.schedule.expression} ${r.schedule.timezone}` : "manual-only";
|
package/dist/products.js
CHANGED