codiedev 0.10.0-beta.15 → 0.10.0-beta.17
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/dist/cli.js +63 -18
- package/dist/codie.js +19 -2
- package/dist/codieLauncher.js +20 -1
- package/dist/commands/agents.js +18 -1
- package/dist/commands/agentsSdk.generated.js +3 -3
- package/dist/commands/inbox.js +9 -0
- package/dist/commands/pack.js +258 -12
- package/dist/commands/ping.js +35 -10
- package/dist/commands/pingFiles.js +145 -0
- package/dist/commands/push.js +33 -4
- package/dist/commands/reply.js +49 -0
- package/dist/commands/scrub.js +1 -2
- package/dist/commands/send.js +11 -51
- package/dist/commands/shared.js +51 -0
- package/dist/commands/work.js +761 -0
- package/dist/connect.js +3 -0
- package/dist/hook.js +50 -5
- package/dist/inboxFormat.js +17 -1
- package/dist/launchContext.js +56 -0
- package/dist/launcher.js +24 -1
- package/dist/localScrub.js +6 -0
- package/dist/localScrubReport.js +4 -2
- package/dist/managedPi.js +1 -0
- package/dist/mcp.js +15 -77
- package/dist/packs/files.js +291 -0
- package/dist/packs/harnesses.js +2 -3
- package/dist/packs/install.js +31 -3
- package/dist/packs/localSkills.js +120 -0
- package/dist/packs/manifest.js +51 -2
- package/dist/packs/skillFiles.js +106 -0
- package/dist/packs/store.js +21 -3
- package/dist/promptGuard.js +223 -0
- package/dist/scrub/rules.js +260 -21
- package/dist/teamSkillContext.js +1 -1
- package/dist/unreadNotice.js +72 -0
- package/dist/utils.js +120 -25
- package/package.json +2 -2
- package/dist/commands/ask.js +0 -55
package/dist/commands/push.js
CHANGED
|
@@ -35,6 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.parseArgs = parseArgs;
|
|
37
37
|
exports.pushFile = pushFile;
|
|
38
|
+
exports.uploadSkillFolder = uploadSkillFolder;
|
|
39
|
+
exports.formatBytes = formatBytes;
|
|
38
40
|
exports.runPush = runPush;
|
|
39
41
|
const fs = __importStar(require("fs"));
|
|
40
42
|
const skillMarker_1 = require("../skillMarker");
|
|
@@ -42,6 +44,7 @@ const path = __importStar(require("path"));
|
|
|
42
44
|
const shared = __importStar(require("./shared"));
|
|
43
45
|
const shared_1 = require("./shared");
|
|
44
46
|
const utils_1 = require("../utils");
|
|
47
|
+
const skillFiles_1 = require("../packs/skillFiles");
|
|
45
48
|
const VALID_TYPES = new Set([
|
|
46
49
|
"spec",
|
|
47
50
|
"bugfix",
|
|
@@ -58,6 +61,7 @@ function parseArgs(args) {
|
|
|
58
61
|
let force = false;
|
|
59
62
|
let as;
|
|
60
63
|
let priv = false;
|
|
64
|
+
let noFiles = false;
|
|
61
65
|
const tags = [];
|
|
62
66
|
for (let i = 0; i < args.length; i++) {
|
|
63
67
|
const a = args[i];
|
|
@@ -91,12 +95,15 @@ function parseArgs(args) {
|
|
|
91
95
|
else if (a === "--private") {
|
|
92
96
|
priv = true;
|
|
93
97
|
}
|
|
98
|
+
else if (a === "--no-files") {
|
|
99
|
+
noFiles = true;
|
|
100
|
+
}
|
|
94
101
|
else if (!a.startsWith("--") && !file) {
|
|
95
102
|
file = a;
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
105
|
if (!file) {
|
|
99
|
-
console.error("Usage: codiedev push <file.md> [--as <key>] [--kind doc|skill] [--tag <name>] [--private] [--force]");
|
|
106
|
+
console.error("Usage: codiedev push <file.md> [--as <key>] [--kind doc|skill] [--tag <name>] [--private] [--force] [--no-files]");
|
|
100
107
|
process.exit(1);
|
|
101
108
|
}
|
|
102
109
|
if (type && !VALID_TYPES.has(type)) {
|
|
@@ -114,7 +121,7 @@ function parseArgs(args) {
|
|
|
114
121
|
process.exit(1);
|
|
115
122
|
}
|
|
116
123
|
}
|
|
117
|
-
return { file, type, kind, tags, force, as, private: priv };
|
|
124
|
+
return { file, type, kind, tags, force, as, private: priv, noFiles };
|
|
118
125
|
}
|
|
119
126
|
async function pushFile(config, opts) {
|
|
120
127
|
const markdown = (0, skillMarker_1.stripSkillMarker)(fs.readFileSync(opts.absPath, "utf8"));
|
|
@@ -131,11 +138,28 @@ async function pushFile(config, opts) {
|
|
|
131
138
|
gitRemoteUrl,
|
|
132
139
|
visibility: opts.visibility,
|
|
133
140
|
contentHash: opts.contentHash,
|
|
141
|
+
...(opts.files ? { files: opts.files } : {}),
|
|
134
142
|
},
|
|
135
143
|
});
|
|
136
144
|
}
|
|
145
|
+
async function uploadSkillFolder(config, skillFile, log = () => { }) {
|
|
146
|
+
const folder = (0, skillFiles_1.skillFolderFiles)(skillFile);
|
|
147
|
+
if (!folder)
|
|
148
|
+
return null;
|
|
149
|
+
if ("skipped" in folder) {
|
|
150
|
+
log(` ! Pushing SKILL.md only: ${folder.skipped}. The skill keeps the files it had.`);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
for (const note of folder.notes)
|
|
154
|
+
log(` · ${note}`);
|
|
155
|
+
await (0, skillFiles_1.uploadBlobs)(config, folder.files, "/api/cli/skills/files");
|
|
156
|
+
return { files: folder.files.map(skillFiles_1.toRef), bytes: folder.bytes };
|
|
157
|
+
}
|
|
158
|
+
function formatBytes(n) {
|
|
159
|
+
return n >= 1024 * 1024 ? `${(n / (1024 * 1024)).toFixed(1)}MB` : n >= 1024 ? `${Math.round(n / 1024)}KB` : `${n}B`;
|
|
160
|
+
}
|
|
137
161
|
async function runPush(args) {
|
|
138
|
-
const { file, type, kind, tags, force, as, private: priv } = parseArgs(args);
|
|
162
|
+
const { file, type, kind, tags, force, as, private: priv, noFiles } = parseArgs(args);
|
|
139
163
|
const config = (0, shared_1.requireConfig)();
|
|
140
164
|
let absolute = file;
|
|
141
165
|
if (!path.isAbsolute(absolute)) {
|
|
@@ -153,6 +177,7 @@ async function runPush(args) {
|
|
|
153
177
|
const filename = as ?? path.basename(absolute);
|
|
154
178
|
const start = Date.now();
|
|
155
179
|
try {
|
|
180
|
+
const folder = !noFiles && kind !== "doc" ? await uploadSkillFolder(config, absolute, (l) => console.log(l)) : null;
|
|
156
181
|
const res = await pushFile(config, {
|
|
157
182
|
absPath: absolute,
|
|
158
183
|
key: filename,
|
|
@@ -161,6 +186,7 @@ async function runPush(args) {
|
|
|
161
186
|
tags,
|
|
162
187
|
force,
|
|
163
188
|
visibility: priv ? "private" : undefined,
|
|
189
|
+
...(folder ? { files: folder.files } : {}),
|
|
164
190
|
});
|
|
165
191
|
(0, shared_1.recordAgentEvent)(config, {
|
|
166
192
|
tool: "codiedev_push",
|
|
@@ -168,7 +194,10 @@ async function runPush(args) {
|
|
|
168
194
|
latencyMs: Date.now() - start,
|
|
169
195
|
});
|
|
170
196
|
const tagSummary = res.tags && res.tags.length > 0 ? ` tags=[${res.tags.join(", ")}]` : "";
|
|
171
|
-
|
|
197
|
+
const fileSummary = folder?.files.length
|
|
198
|
+
? `, with ${folder.files.length} file${folder.files.length === 1 ? "" : "s"} from its folder, ${formatBytes(folder.bytes)}`
|
|
199
|
+
: "";
|
|
200
|
+
console.log(`✓ Pushed ${filename} (kind=${res.kind}${tagSummary}${fileSummary}).`);
|
|
172
201
|
console.log(` Visible under: ${res.destination}`);
|
|
173
202
|
if (res.key && res.key !== filename) {
|
|
174
203
|
console.log(` Stored as: ${res.key}`);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runReply = runReply;
|
|
4
|
+
const shared_1 = require("./shared");
|
|
5
|
+
const pingFiles_1 = require("./pingFiles");
|
|
6
|
+
const USAGE = 'Usage: codiedev reply <ping-id> "<message>" [--file <path>]';
|
|
7
|
+
async function runReply(args) {
|
|
8
|
+
const { files, rest } = (0, pingFiles_1.takeFileArgs)(args);
|
|
9
|
+
const positional = rest.filter((a) => !a.startsWith("--"));
|
|
10
|
+
const pingId = positional[0];
|
|
11
|
+
const body = (0, shared_1.stripQuotes)(positional.slice(1).join(" "));
|
|
12
|
+
if (!pingId || (!body && files.length === 0)) {
|
|
13
|
+
console.error(USAGE);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const config = (0, shared_1.requireConfig)();
|
|
17
|
+
const start = Date.now();
|
|
18
|
+
try {
|
|
19
|
+
const attachmentIds = await (0, pingFiles_1.uploadOrExit)(config, files);
|
|
20
|
+
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/reply", {
|
|
21
|
+
config,
|
|
22
|
+
body: { pingId, body, ...(attachmentIds.length ? { attachmentIds } : {}) },
|
|
23
|
+
});
|
|
24
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
25
|
+
tool: "codiedev_reply",
|
|
26
|
+
ok: true,
|
|
27
|
+
latencyMs: Date.now() - start,
|
|
28
|
+
});
|
|
29
|
+
const to = res.recipient ? `${res.recipient.name} <${res.recipient.email}>` : "them";
|
|
30
|
+
const withFiles = files.length ? ` with ${files.length} file${files.length === 1 ? "" : "s"}` : "";
|
|
31
|
+
console.log(`✓ Replied to ${to}${withFiles}`);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const e = err;
|
|
35
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
36
|
+
tool: "codiedev_reply",
|
|
37
|
+
ok: false,
|
|
38
|
+
latencyMs: Date.now() - start,
|
|
39
|
+
error: e.message,
|
|
40
|
+
});
|
|
41
|
+
if (e.status === 404 && /ping not found/.test(e.message)) {
|
|
42
|
+
console.error(`No ping ${pingId} addressed to you. Run 'codiedev inbox' for the ids.`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.error(`Reply failed: ${e.message}`);
|
|
46
|
+
}
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
package/dist/commands/scrub.js
CHANGED
|
@@ -27,8 +27,7 @@ your credential files and .env files) if your admin allows it. It reads
|
|
|
27
27
|
~/.aws/credentials, ~/.npmrc, ~/.pypirc, ~/.netrc, ~/.git-credentials,
|
|
28
28
|
~/.config/gh/hosts.yml, ~/.docker/config.json, ~/.config/hub,
|
|
29
29
|
~/.gem/credentials, ~/.config/openai/credentials, and .env / .env.* in the
|
|
30
|
-
repos your sessions start in. Values stay on this machine
|
|
31
|
-
chose to check uploaded sessions too is a keyed fingerprint of each sent.
|
|
30
|
+
repos your sessions start in. Values stay on this machine.
|
|
32
31
|
`;
|
|
33
32
|
function parseScrubArgs(args) {
|
|
34
33
|
let dryRun = false;
|
package/dist/commands/send.js
CHANGED
|
@@ -1,62 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendToPingArgs = sendToPingArgs;
|
|
3
4
|
exports.runSend = runSend;
|
|
5
|
+
const ping_1 = require("./ping");
|
|
4
6
|
const shared_1 = require("./shared");
|
|
5
|
-
function
|
|
7
|
+
function sendToPingArgs(args) {
|
|
6
8
|
const positionals = args.filter((a) => !a.startsWith("--"));
|
|
7
9
|
const [filename, to, ...rest] = positionals;
|
|
8
|
-
if (!filename || !to)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const message = rest.length > 0 ? (0, shared_1.stripQuotes)(rest.join(" ")) : undefined;
|
|
13
|
-
return { filename, to, message };
|
|
10
|
+
if (!filename || !to)
|
|
11
|
+
return null;
|
|
12
|
+
const message = rest.length > 0 ? (0, shared_1.stripQuotes)(rest.join(" ")) : "";
|
|
13
|
+
return [to, ...(message ? [message] : []), "--with", filename];
|
|
14
14
|
}
|
|
15
15
|
async function runSend(args, configOverride) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
const body = {
|
|
21
|
-
filename: parsed.filename,
|
|
22
|
-
to: parsed.to,
|
|
23
|
-
};
|
|
24
|
-
if (parsed.message)
|
|
25
|
-
body.message = parsed.message;
|
|
26
|
-
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/send-to", {
|
|
27
|
-
config,
|
|
28
|
-
body,
|
|
29
|
-
});
|
|
30
|
-
(0, shared_1.recordAgentEvent)(config, {
|
|
31
|
-
tool: "codiedev_send_to",
|
|
32
|
-
ok: true,
|
|
33
|
-
latencyMs: Date.now() - start,
|
|
34
|
-
});
|
|
35
|
-
const who = res.recipient ? `${res.recipient.name} (${res.recipient.email})` : parsed.to;
|
|
36
|
-
if (parsed.message) {
|
|
37
|
-
console.log(`Sent ${parsed.filename} to ${who}.`);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
console.log(`Shared ${parsed.filename} with ${who} (no message).`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
(0, shared_1.recordAgentEvent)(config, {
|
|
45
|
-
tool: "codiedev_send_to",
|
|
46
|
-
ok: false,
|
|
47
|
-
latencyMs: Date.now() - start,
|
|
48
|
-
error: err.message,
|
|
49
|
-
});
|
|
50
|
-
const body = err.body;
|
|
51
|
-
if (body && Array.isArray(body.candidates) && body.candidates.length > 0) {
|
|
52
|
-
console.error(`Recipient "${parsed.to}" is ambiguous. Candidates:`);
|
|
53
|
-
for (const c of body.candidates) {
|
|
54
|
-
console.error(` - ${c.name} (${c.email})`);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
console.error(`Send failed: ${err.message}`);
|
|
59
|
-
}
|
|
16
|
+
const pingArgs = sendToPingArgs(args);
|
|
17
|
+
if (!pingArgs) {
|
|
18
|
+
console.error('Usage: codiedev send <artifact> <recipient> ["<message>"] (same as: codiedev ping <recipient> ["<message>"] --with <artifact>)');
|
|
60
19
|
process.exit(1);
|
|
61
20
|
}
|
|
21
|
+
await (0, ping_1.runPing)(pingArgs, configOverride);
|
|
62
22
|
}
|
package/dist/commands/shared.js
CHANGED
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.applyConfigEnvOverrides = applyConfigEnvOverrides;
|
|
37
37
|
exports.requireConfig = requireConfig;
|
|
38
38
|
exports.apiRequest = apiRequest;
|
|
39
|
+
exports.apiRequestBytes = apiRequestBytes;
|
|
39
40
|
exports.recordAgentEvent = recordAgentEvent;
|
|
40
41
|
exports.recordInstallEvent = recordInstallEvent;
|
|
41
42
|
exports.withTelemetry = withTelemetry;
|
|
@@ -120,6 +121,56 @@ function apiRequest(method, path, options) {
|
|
|
120
121
|
req.end();
|
|
121
122
|
});
|
|
122
123
|
}
|
|
124
|
+
function apiRequestBytes(method, path, options) {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
const url = new URL(path, options.config.backendUrl);
|
|
127
|
+
for (const [k, v] of Object.entries(options.query ?? {})) {
|
|
128
|
+
if (v !== undefined)
|
|
129
|
+
url.searchParams.set(k, String(v));
|
|
130
|
+
}
|
|
131
|
+
const lib = url.protocol === "https:" ? https : http;
|
|
132
|
+
const req = lib.request({
|
|
133
|
+
hostname: url.hostname,
|
|
134
|
+
port: url.port || (url.protocol === "https:" ? 443 : 80),
|
|
135
|
+
path: url.pathname + url.search,
|
|
136
|
+
method,
|
|
137
|
+
headers: {
|
|
138
|
+
Authorization: `Bearer ${options.config.token}`,
|
|
139
|
+
"X-Codiedev-Cli-Version": version_1.CLI_VERSION,
|
|
140
|
+
...(options.body ? { "Content-Type": "application/octet-stream", "Content-Length": options.body.length } : {}),
|
|
141
|
+
},
|
|
142
|
+
}, (res) => {
|
|
143
|
+
const chunks = [];
|
|
144
|
+
let size = 0;
|
|
145
|
+
res.on("data", (c) => {
|
|
146
|
+
size += c.length;
|
|
147
|
+
if (options.maxBytes !== undefined && size > options.maxBytes) {
|
|
148
|
+
req.destroy(Object.assign(new Error(`response over ${options.maxBytes} bytes`), { status: res.statusCode }));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
chunks.push(c);
|
|
152
|
+
});
|
|
153
|
+
res.on("end", () => {
|
|
154
|
+
const buf = Buffer.concat(chunks);
|
|
155
|
+
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300)
|
|
156
|
+
return resolve(buf);
|
|
157
|
+
let message = `HTTP ${res.statusCode}`;
|
|
158
|
+
try {
|
|
159
|
+
const parsed = JSON.parse(buf.toString("utf8"));
|
|
160
|
+
if (parsed && typeof parsed.error === "string")
|
|
161
|
+
message = parsed.error;
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
}
|
|
165
|
+
reject(Object.assign(new Error(message), { status: res.statusCode }));
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
req.on("error", reject);
|
|
169
|
+
if (options.body)
|
|
170
|
+
req.write(options.body);
|
|
171
|
+
req.end();
|
|
172
|
+
});
|
|
173
|
+
}
|
|
123
174
|
function recordAgentEvent(config, event) {
|
|
124
175
|
apiRequest("POST", "/api/telemetry/mcp-event", {
|
|
125
176
|
config,
|