codiedev 0.9.88 → 0.9.89

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.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * codiedev connect — link agent CLIs to your org
7
7
  * codiedev push <file> — author/update a spec/review/decision/etc.
8
8
  * codiedev pull <key> — fetch an artifact by filename key
9
- * codiedev ping <user> "<msg>" — send a message (optionally --with <key>)
9
+ * codiedev ping <user> ["<msg>"] — message and/or share (--with <key>)
10
10
  * codiedev inbox — list pings (use --unread to filter)
11
11
  * codiedev read <ping-id> — mark read + show full message
12
12
  * codiedev reply <ping-id> "<msg>" — answer a ping in its thread
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * codiedev connect — link agent CLIs to your org
8
8
  * codiedev push <file> — author/update a spec/review/decision/etc.
9
9
  * codiedev pull <key> — fetch an artifact by filename key
10
- * codiedev ping <user> "<msg>" — send a message (optionally --with <key>)
10
+ * codiedev ping <user> ["<msg>"] — message and/or share (--with <key>)
11
11
  * codiedev inbox — list pings (use --unread to filter)
12
12
  * codiedev read <ping-id> — mark read + show full message
13
13
  * codiedev reply <ping-id> "<msg>" — answer a ping in its thread
@@ -103,11 +103,10 @@ Artifacts:
103
103
  Asks for confirmation; -y to skip.
104
104
 
105
105
  Messaging:
106
- codiedev ping <user> "<msg>" [--with <key>] [--file <path>]
107
- Send a message to a teammate
108
- codiedev send <key> <user> ["<msg>"] Share an artifact + ping in one step
109
- codiedev share <key> <user> [--role read|edit]
110
- Silently grant access (no notification)
106
+ codiedev ping <user> ["<msg>"] [--with <key>] [--edit] [--file <path>]
107
+ Message a teammate (emails them). --with
108
+ gives them access to an artifact; with
109
+ no message it's a silent share
111
110
  codiedev inbox [--unread] [--limit N] Show messages
112
111
  codiedev read <ping-id> Mark read + show full message
113
112
  codiedev reply <ping-id> "<msg>" [--file <path>]
@@ -280,10 +279,14 @@ codiedev pull — fetch an artifact
280
279
  codiedev pull spec-cart-clear.md | less
281
280
  `.trim(),
282
281
  ping: `
283
- codiedev ping — send a teammate a message, optionally attached to an artifact
282
+ codiedev ping — send a teammate a message, an artifact, or both
284
283
 
285
284
  Usage:
286
- codiedev ping <user> "<message>" [--with <artifact-key>] [--file <path>]
285
+ codiedev ping <user> ["<message>"] [--with <artifact-key>] [--edit] [--file <path>]
286
+
287
+ --with gives them read access to the artifact (--edit: edit access; only
288
+ the owner can give edit access or share a private skill). With no message,
289
+ it's a silent share: access only, no inbox entry, no email.
287
290
 
288
291
  <user> resolves to a teammate in your org by first name, full name,
289
292
  or email. Ambiguous matches return a list — retry with the full email.
@@ -1 +1,10 @@
1
- export declare function runPing(args: string[]): Promise<void>;
1
+ import type { CodiedevConfig } from "../utils";
2
+ export declare const PING_USAGE = "Usage: codiedev ping <user> [\"<message>\"] [--with <artifact-key>] [--edit] [--file <path>]";
3
+ export declare function parsePingArgs(allArgs: string[]): {
4
+ to: string;
5
+ body: string;
6
+ subjectKey?: string;
7
+ edit: boolean;
8
+ files: string[];
9
+ };
10
+ export declare function runPing(args: string[], configOverride?: CodiedevConfig): Promise<void>;
@@ -1,16 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PING_USAGE = void 0;
4
+ exports.parsePingArgs = parsePingArgs;
3
5
  exports.runPing = runPing;
6
+ // `codiedev ping <user> ["<message>"] [--with <artifact>] [--edit] [--file <path>]`
7
+ // The one way to send a teammate something:
8
+ // message only → inbox + email
9
+ // message + --with → inbox + email, and they get access to the artifact
10
+ // --with, no message → access only, no notification (what `share` did)
11
+ // `send` and `share` are kept as aliases that route here.
4
12
  const shared_1 = require("./shared");
5
13
  const pingFiles_1 = require("./pingFiles");
6
- function parseArgs(allArgs) {
14
+ const share_1 = require("./share");
15
+ exports.PING_USAGE = 'Usage: codiedev ping <user> ["<message>"] [--with <artifact-key>] [--edit] [--file <path>]';
16
+ function parsePingArgs(allArgs) {
7
17
  const { files, rest: args } = (0, pingFiles_1.takeFileArgs)(allArgs);
8
18
  let to;
9
19
  const positional = [];
10
20
  let subjectKey;
21
+ let edit = false;
11
22
  for (let i = 0; i < args.length; i++) {
12
23
  const a = args[i];
13
- if ((a === "--with" || a === "-w") && i + 1 < args.length) {
24
+ if (a === "--edit") {
25
+ edit = true;
26
+ }
27
+ else if ((a === "--with" || a === "-w") && i + 1 < args.length) {
14
28
  subjectKey = args[++i];
15
29
  }
16
30
  else if (a.startsWith("--with=")) {
@@ -20,26 +34,41 @@ function parseArgs(allArgs) {
20
34
  positional.push(a);
21
35
  }
22
36
  }
23
- // A file can stand in for the message.
24
- if (positional.length < 2 && !(positional.length === 1 && files.length > 0)) {
25
- console.error("Usage: codiedev ping <user> \"<message>\" [--with <artifact-key>] [--file <path>]");
37
+ // A file can stand in for the message; --with alone shares without one.
38
+ if (positional.length < 2 && !(positional.length === 1 && (files.length > 0 || subjectKey))) {
39
+ console.error(exports.PING_USAGE);
40
+ process.exit(1);
41
+ }
42
+ if (edit && !subjectKey) {
43
+ console.error("--edit needs an artifact: --with <artifact-key>");
26
44
  process.exit(1);
27
45
  }
28
46
  to = positional[0];
29
47
  // Join remaining positionals in case the shell split the message on spaces
30
48
  // despite quoting (happens with some escape sequences).
31
49
  const body = (0, shared_1.stripQuotes)(positional.slice(1).join(" "));
32
- return { to, body: body || (files.length ? "Sent a file." : ""), subjectKey, files };
50
+ return { to, body: body || (files.length ? "Sent a file." : ""), subjectKey, edit, files };
33
51
  }
34
- async function runPing(args) {
35
- const { to, body, subjectKey, files } = parseArgs(args);
36
- const config = (0, shared_1.requireConfig)();
52
+ async function runPing(args, configOverride) {
53
+ const { to, body, subjectKey, edit, files } = parsePingArgs(args);
54
+ // Nothing to say, just access: a silent share.
55
+ if (!body && subjectKey) {
56
+ await (0, share_1.runShare)([subjectKey, to, "--role", edit ? "edit" : "read"], configOverride);
57
+ return;
58
+ }
59
+ const config = configOverride ?? (0, shared_1.requireConfig)();
37
60
  const start = Date.now();
38
61
  try {
39
62
  const attachmentIds = await (0, pingFiles_1.uploadOrExit)(config, files);
40
63
  const res = await (0, shared_1.apiRequest)("POST", "/api/cli/ping", {
41
64
  config,
42
- body: { to, body, subjectKey, ...(attachmentIds.length ? { attachmentIds } : {}) },
65
+ body: {
66
+ to,
67
+ body,
68
+ subjectKey,
69
+ ...(subjectKey ? { grant: edit ? "edit" : "read" } : {}),
70
+ ...(attachmentIds.length ? { attachmentIds } : {}),
71
+ },
43
72
  });
44
73
  (0, shared_1.recordAgentEvent)(config, {
45
74
  tool: "codiedev_ping",
@@ -1,2 +1,3 @@
1
1
  import type { CodiedevConfig } from "../utils";
2
+ export declare function sendToPingArgs(args: string[]): string[] | null;
2
3
  export declare function runSend(args: string[], configOverride?: CodiedevConfig): Promise<void>;
@@ -1,67 +1,27 @@
1
1
  "use strict";
2
- // `codiedev send <filename> <recipient> [message]` — share an artifact AND
3
- // send a short message that lands in the teammate's inbox. The active-
4
- // handoff version of `codiedev share`. Use this when the user is actively
5
- // looping someone in.
6
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendToPingArgs = sendToPingArgs;
7
4
  exports.runSend = runSend;
5
+ // `codiedev send <artifact> <recipient> ["<message>"]` — kept as an alias for
6
+ // `codiedev ping <recipient> ["<message>"] --with <artifact>`. With a message
7
+ // the teammate gets it in their inbox and by email plus read access; without
8
+ // one it's a silent share.
9
+ const ping_1 = require("./ping");
8
10
  const shared_1 = require("./shared");
9
- function parseArgs(args) {
11
+ function sendToPingArgs(args) {
10
12
  const positionals = args.filter((a) => !a.startsWith("--"));
11
13
  const [filename, to, ...rest] = positionals;
12
- if (!filename || !to) {
13
- console.error('Usage: codiedev send <filename> <recipient> ["<message>"]');
14
- process.exit(1);
15
- }
14
+ if (!filename || !to)
15
+ return null;
16
16
  // Recombine remaining tokens — supports both quoted and unquoted messages.
17
- const message = rest.length > 0 ? (0, shared_1.stripQuotes)(rest.join(" ")) : undefined;
18
- return { filename, to, message };
17
+ const message = rest.length > 0 ? (0, shared_1.stripQuotes)(rest.join(" ")) : "";
18
+ return [to, ...(message ? [message] : []), "--with", filename];
19
19
  }
20
20
  async function runSend(args, configOverride) {
21
- const parsed = parseArgs(args);
22
- const config = configOverride ?? (0, shared_1.requireConfig)();
23
- const start = Date.now();
24
- try {
25
- const body = {
26
- filename: parsed.filename,
27
- to: parsed.to,
28
- };
29
- if (parsed.message)
30
- body.message = parsed.message;
31
- const res = await (0, shared_1.apiRequest)("POST", "/api/cli/send-to", {
32
- config,
33
- body,
34
- });
35
- (0, shared_1.recordAgentEvent)(config, {
36
- tool: "codiedev_send_to",
37
- ok: true,
38
- latencyMs: Date.now() - start,
39
- });
40
- const who = res.recipient ? `${res.recipient.name} (${res.recipient.email})` : parsed.to;
41
- if (parsed.message) {
42
- console.log(`Sent ${parsed.filename} to ${who}.`);
43
- }
44
- else {
45
- console.log(`Shared ${parsed.filename} with ${who} (no message).`);
46
- }
47
- }
48
- catch (err) {
49
- (0, shared_1.recordAgentEvent)(config, {
50
- tool: "codiedev_send_to",
51
- ok: false,
52
- latencyMs: Date.now() - start,
53
- error: err.message,
54
- });
55
- const body = err.body;
56
- if (body && Array.isArray(body.candidates) && body.candidates.length > 0) {
57
- console.error(`Recipient "${parsed.to}" is ambiguous. Candidates:`);
58
- for (const c of body.candidates) {
59
- console.error(` - ${c.name} (${c.email})`);
60
- }
61
- }
62
- else {
63
- console.error(`Send failed: ${err.message}`);
64
- }
21
+ const pingArgs = sendToPingArgs(args);
22
+ if (!pingArgs) {
23
+ console.error('Usage: codiedev send <artifact> <recipient> ["<message>"] (same as: codiedev ping <recipient> ["<message>"] --with <artifact>)');
65
24
  process.exit(1);
66
25
  }
26
+ await (0, ping_1.runPing)(pingArgs, configOverride);
67
27
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // `codiedev share <filename> <recipient> [--role read|edit]` — silently
3
- // grant a teammate access to an artifact (no notification). Use
4
- // `codiedev send` instead when the user wants to actively loop someone in.
3
+ // grant a teammate access to an artifact (no notification). Kept as an alias:
4
+ // `codiedev ping <recipient> --with <filename> [--edit]` lands here too.
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.runShare = runShare;
7
7
  const shared_1 = require("./shared");
package/dist/mcp.js CHANGED
@@ -174,10 +174,10 @@ const TOOLS = [
174
174
  },
175
175
  {
176
176
  name: "codiedev_ping",
177
- description: "Send a message to a teammate on Codiedev, optionally attached to a " +
178
- "specific artifact. Use when the user asks to ping, ask, share with, " +
179
- "or get feedback from a teammate by name (e.g. 'ping a teammate about " +
180
- "this spec'). Recipients are resolved by first name, full name, or email " +
177
+ description: "Send a message to a teammate on Codiedev, optionally with an " +
178
+ "artifact (they also get read access to it). Use when the user asks to " +
179
+ "ping, ask, send something to, or get feedback from a teammate by name " +
180
+ "(e.g. 'send this spec to a teammate'). Recipients are resolved by first name, full name, or email " +
181
181
  "within the current org. They're notified by email and can reply " +
182
182
  "from their own agent.",
183
183
  inputSchema: {
@@ -194,8 +194,13 @@ const TOOLS = [
194
194
  },
195
195
  subjectKey: {
196
196
  type: "string",
197
- description: "Optional filename key of an artifact the message is about " +
198
- "(e.g. 'spec-214.md'). Leaving blank sends a standalone ping.",
197
+ description: "Optional filename key of an artifact to send (e.g. " +
198
+ "'spec-214.md'). The teammate also gets read access to it. " +
199
+ "Leaving blank sends a standalone ping.",
200
+ },
201
+ edit: {
202
+ type: "boolean",
203
+ description: "With subjectKey: give edit access instead of read (owner only).",
199
204
  },
200
205
  },
201
206
  required: ["to", "body"],
@@ -245,7 +250,7 @@ const TOOLS = [
245
250
  "without sending a notification. Use when the user says 'share this " +
246
251
  "with a teammate' or 'give someone access', and doesn't want to surface " +
247
252
  "it as a message. If they want the teammate actively notified, use " +
248
- "codiedev_send_to instead.",
253
+ "codiedev_ping with subjectKey instead.",
249
254
  inputSchema: {
250
255
  type: "object",
251
256
  properties: {
@@ -264,27 +269,6 @@ const TOOLS = [
264
269
  required: ["filename", "to"],
265
270
  },
266
271
  },
267
- {
268
- name: "codiedev_send_to",
269
- description: "Grant access to an artifact AND send a short message to a " +
270
- "teammate. Use when the user asks to 'send this to a teammate', 'ask " +
271
- "someone to look at this', or 'share this with a teammate and tell them X'. " +
272
- "This is the active handoff version of codiedev_share_with — the " +
273
- "recipient gets a ping in their inbox.",
274
- inputSchema: {
275
- type: "object",
276
- properties: {
277
- filename: { type: "string", description: "Artifact filename." },
278
- to: { type: "string", description: "Teammate first name, full name, or email." },
279
- message: {
280
- type: "string",
281
- description: "Optional short note to send with the share. If omitted, only " +
282
- "the grant is created (no ping).",
283
- },
284
- },
285
- required: ["filename", "to"],
286
- },
287
- },
288
272
  {
289
273
  name: "codiedev_search",
290
274
  description: "Search the team's artifact library by natural-language query. Use " +
@@ -534,12 +518,13 @@ async function handlePing(args, config) {
534
518
  const to = asString(args.to);
535
519
  const body = asString(args.body);
536
520
  const subjectKey = asStringOrUndefined(args.subjectKey);
521
+ const grant = subjectKey ? (args.edit === true ? "edit" : "read") : undefined;
537
522
  if (!to)
538
523
  throw new Error("to required");
539
524
  if (!body)
540
525
  throw new Error("body required");
541
526
  try {
542
- const res = await (0, shared_1.apiRequest)("POST", "/api/cli/ping", { config, body: { to, body, subjectKey } });
527
+ const res = await (0, shared_1.apiRequest)("POST", "/api/cli/ping", { config, body: { to, body, subjectKey, ...(grant ? { grant } : {}) } });
543
528
  return {
544
529
  content: [
545
530
  {
package/dist/utils.d.ts CHANGED
@@ -143,7 +143,7 @@ export declare function ensureAllCodiedevHooksInstalled(): void;
143
143
  export declare function hasDirectHookPath(configText: string): boolean;
144
144
  export declare function migrateHooksToLauncher(): string[];
145
145
  export declare function ensureSessionStartHookInstalled(): void;
146
- export declare const CODIEDEV_INSTRUCTIONS_BODY = "## Codiedev \u2014 team artifact layer\n\nThis machine is connected to Codiedev. Teammates share specs, reviews,\ndecisions, and messages via a CLI on every dev's machine.\n\n**When the user asks to share, push, ping, check messages, or capture a\nthought, use the `codiedev` CLI via Bash:**\n\n| Intent | Command |\n|---|---|\n| \"push this spec\" / \"save this as a skill\" | `codiedev push <file.md>` |\n| \"pull X\" / \"grab the latest spec-X\" / \"what did a teammate push?\" | `codiedev pull <key>` |\n| \"delete X\" / \"remove that test push\" / \"rm spec-old\" | `codiedev delete <key>` (always confirm with the user first) |\n| \"ping a teammate about this\" / \"ask someone for their take\" / \"send them this file\" | `codiedev ping <name> \"<msg>\" [--with <key>] [--file <path>]` |\n| \"any messages?\" / \"check my inbox\" / \"what did a teammate say?\" | `codiedev inbox` |\n| \"read that reply\" / \"mark that ping read\" | `codiedev read <ping-id>` |\n| \"reply to that\" / \"tell them X\" (answering a message from `codiedev inbox`) | `codiedev reply <ping-id> \"<msg>\" [--file <path>]` (not a new ping: this threads it and marks theirs answered) |\n| \"note that X is a follow-up\" / \"remember X\" | `codiedev note \"<text>\"` |\n| \"share with a teammate\" / \"give someone access\" (no notification) | `codiedev share <key> <name> [--role read\\|edit]` |\n| \"send this to a teammate\" / \"ask someone to look at this\" | `codiedev send <key> <name> [\"<msg>\"]` |\n| \"find something about X\" / \"has anyone solved Y?\" | `codiedev search \"<query>\" [--limit N]` |\n| \"show my library\" / \"what artifacts exist?\" | `codiedev library [--scope mine\\|shared\\|all] [--kind doc\\|skill]` |\n| \"run my agent's test cases\" / \"check the dataset on model Y\" / \"run v2 of the dataset\" | `codiedev traces cases <agent> [--dataset <name> [--version <n>]] [--model <id>]` (writes cases + RUN_CASES.md + results.json; follow it, then `codiedev traces report <results.json>`) |\n| \"how are my agents doing?\" / \"what's failing this week?\" / \"show the booking agent's failed runs\" / \"why did run X fail?\" | `codiedev traces overview`; `codiedev traces runs <agent> [--failed] [--flag <issue>] [--days n]`; `codiedev traces run <run> --agent <name>` (add `--json` to read the data yourself) |\n| \"add a helpfulness 1\u20135 score\" / \"make a review queue for tone\" | `codiedev traces score-kinds add <name> --type number --min 1 --max 5`; `codiedev traces queue create <name> --scores <a,b>` |\n| \"score that run 4 for helpfulness\" / \"how is my agent scoring?\" | `codiedev traces score <run> <score> <value> [--agent <name>] [--comment <why>]`; `codiedev traces scores <agent>` |\n| \"put this week's failed runs in the review queue\" | `codiedev traces queue list`; `codiedev traces queue add <queue> --agent <name> [--failed] [--days n]` |\n| \"have a judge score 10% of my agent's runs\" / \"turn off automatic scoring\" | `codiedev traces judge <agent> --on --scores <a,b> --sample 10 [--budget 25]`; `--off`; no flags shows it |\n| \"import these test cases from a CSV\" / \"add an example to the dataset\" / \"save the dataset as a version\" | `codiedev traces import <agent> <file> --dataset <name>`; `codiedev traces add-example <agent> --dataset <name> --input \"\u2026\" [--expected \"\u2026\"]`; `codiedev traces save-version <dataset>`; `codiedev traces versions <dataset>` |\n| \"make a starter pack\" / \"add this to our pack\" / \"package these skills for my team\" | write a `<slug>.pack.md` (start from `codiedev pack export <slug> --manifest --out .` for an existing pack), then `codiedev pack apply <file> [--publish]` \u2014 see **Starter packs** below |\n| \"publish the pack\" / \"ship the pack to my team\" | `codiedev pack publish <slug> [--channel stable\\|beta\\|alpha]` |\n| \"what was the last eval on X?\" / \"file these eval results\" | `codiedev evals last <subject>` before starting a related eval; `codiedev evals report <run.json>` after each variant runs (scores only \u2014 `codiedev evals help` for the shape) |\n\n**Starter packs** (team managers and admins): a pack.md is frontmatter\n(`name:`, `slug:`, optional `description:`) then sections. Ask the user\nwhat to include, write the file, run `codiedev pack apply <file> --dry-run`\nto show them, then apply for real:\n\n```\n---\nname: \"Healthcare scan\"\nslug: \"healthcare-scan\"\n---\n\n# Healthcare scan\n\n## Skills\n\n- ./skills/healthcare-scan\n- lint.md @teammate@example.com\n\n## Files\n\n- runner <- ~/.claude/runner\n```\n\nUnder **Skills**, a local path (`./\u2026`, `~/\u2026` or `/\u2026`) to a skill folder\nor SKILL.md is pushed to the library and added, with the rest of its folder\nshipped as the skill's files; `<key> @<author email>` adds a teammate's\nlibrary skill. **Files** maps local folders to paths in the pack\n(`.` is the pack root). In skills, point at shipped files relative to the\nskill's folder or with `${CLAUDE_PLUGIN_ROOT}/\u2026`. Applying changes the\ndraft; `--publish` (or `codiedev pack publish`) sends it to the team.\n\n**Just push the file \u2014 we'll figure out where it goes.** Every artifact\nis classified into one of two kinds at upload time:\n\n- **skill** \u2014 the file has SKILL.md frontmatter (`name:` + `description:`\n inside a `---` block). Shows on the Skills page in the portal and is\n invokable as a slash command (`/<name>`).\n- **doc** \u2014 everything else. Lives in the library: list it with\n `codiedev library`, fetch it with `codiedev pull <key>`.\n\nDetection is content-based, not filename-based. The filename prefix\n(`spec-` / `decision-` / `proposal-` / `bugfix-` / `review-` /\n`note-`) is preserved as a *tag* you can filter by, but it never gates\nvisibility. A SKILL-frontmatter file named `note-foo.md` still becomes\na skill.\n\nThe `codiedev push` response always says where the artifact landed \u2014\nread it back to the user so they can confirm.\n\n**Resolving \"the spec we just worked on\":**\n- If a file was recently edited in this session matching the conventions\n above, push that file.\n- If content was drafted inline in the conversation, write it to a file\n first (e.g., `/tmp/spec-xxx.md`) then push.\n\n**Teammate names:** first name usually works (`codiedev ping <name> ...`).\nIf ambiguous, the CLI returns candidates \u2014 retry with the full email.\n\n**Search before pushing.** For any \"save this as \u2026\" request, run\n`codiedev search \"<query>\"` first. If prior art exists, pull it and\niterate rather than duplicating.\n\n**Sharing vs sending:** `codiedev share` is silent (access only, no\nnotification). `codiedev send` both grants access AND pings the\nrecipient. Use send when the user is actively looping someone in.\n\n**Errors:**\n- \"not connected\" \u2192 user needs to run `npx codiedev connect` with their\n API token from https://codiedev.com/portal/integrations/claude-code\n- \"ambiguous recipient\" \u2192 surface candidates to the user\n";
146
+ export declare const CODIEDEV_INSTRUCTIONS_BODY = "## Codiedev \u2014 team artifact layer\n\nThis machine is connected to Codiedev. Teammates share specs, reviews,\ndecisions, and messages via a CLI on every dev's machine.\n\n**When the user asks to share, push, ping, check messages, or capture a\nthought, use the `codiedev` CLI via Bash:**\n\n| Intent | Command |\n|---|---|\n| \"push this spec\" / \"save this as a skill\" | `codiedev push <file.md>` |\n| \"pull X\" / \"grab the latest spec-X\" / \"what did a teammate push?\" | `codiedev pull <key>` |\n| \"delete X\" / \"remove that test push\" / \"rm spec-old\" | `codiedev delete <key>` (always confirm with the user first) |\n| \"ping a teammate about this\" / \"send them this spec\" / \"send them this file\" | `codiedev ping <name> \"<msg>\" [--with <key>] [--file <path>]` (`--with` also gives them access) |\n| \"any messages?\" / \"check my inbox\" / \"what did a teammate say?\" | `codiedev inbox` |\n| \"read that reply\" / \"mark that ping read\" | `codiedev read <ping-id>` |\n| \"reply to that\" / \"tell them X\" (answering a message from `codiedev inbox`) | `codiedev reply <ping-id> \"<msg>\" [--file <path>]` (not a new ping: this threads it and marks theirs answered) |\n| \"note that X is a follow-up\" / \"remember X\" | `codiedev note \"<text>\"` |\n| \"share with a teammate\" / \"give someone access\" (no notification) | `codiedev ping <name> --with <key> [--edit]` (no message = silent share) |\n| \"find something about X\" / \"has anyone solved Y?\" | `codiedev search \"<query>\" [--limit N]` |\n| \"show my library\" / \"what artifacts exist?\" | `codiedev library [--scope mine\\|shared\\|all] [--kind doc\\|skill]` |\n| \"run my agent's test cases\" / \"check the dataset on model Y\" / \"run v2 of the dataset\" | `codiedev traces cases <agent> [--dataset <name> [--version <n>]] [--model <id>]` (writes cases + RUN_CASES.md + results.json; follow it, then `codiedev traces report <results.json>`) |\n| \"how are my agents doing?\" / \"what's failing this week?\" / \"show the booking agent's failed runs\" / \"why did run X fail?\" | `codiedev traces overview`; `codiedev traces runs <agent> [--failed] [--flag <issue>] [--days n]`; `codiedev traces run <run> --agent <name>` (add `--json` to read the data yourself) |\n| \"add a helpfulness 1\u20135 score\" / \"make a review queue for tone\" | `codiedev traces score-kinds add <name> --type number --min 1 --max 5`; `codiedev traces queue create <name> --scores <a,b>` |\n| \"score that run 4 for helpfulness\" / \"how is my agent scoring?\" | `codiedev traces score <run> <score> <value> [--agent <name>] [--comment <why>]`; `codiedev traces scores <agent>` |\n| \"put this week's failed runs in the review queue\" | `codiedev traces queue list`; `codiedev traces queue add <queue> --agent <name> [--failed] [--days n]` |\n| \"have a judge score 10% of my agent's runs\" / \"turn off automatic scoring\" | `codiedev traces judge <agent> --on --scores <a,b> --sample 10 [--budget 25]`; `--off`; no flags shows it |\n| \"import these test cases from a CSV\" / \"add an example to the dataset\" / \"save the dataset as a version\" | `codiedev traces import <agent> <file> --dataset <name>`; `codiedev traces add-example <agent> --dataset <name> --input \"\u2026\" [--expected \"\u2026\"]`; `codiedev traces save-version <dataset>`; `codiedev traces versions <dataset>` |\n| \"make a starter pack\" / \"add this to our pack\" / \"package these skills for my team\" | write a `<slug>.pack.md` (start from `codiedev pack export <slug> --manifest --out .` for an existing pack), then `codiedev pack apply <file> [--publish]` \u2014 see **Starter packs** below |\n| \"publish the pack\" / \"ship the pack to my team\" | `codiedev pack publish <slug> [--channel stable\\|beta\\|alpha]` |\n| \"what was the last eval on X?\" / \"file these eval results\" | `codiedev evals last <subject>` before starting a related eval; `codiedev evals report <run.json>` after each variant runs (scores only \u2014 `codiedev evals help` for the shape) |\n\n**Starter packs** (team managers and admins): a pack.md is frontmatter\n(`name:`, `slug:`, optional `description:`) then sections. Ask the user\nwhat to include, write the file, run `codiedev pack apply <file> --dry-run`\nto show them, then apply for real:\n\n```\n---\nname: \"Healthcare scan\"\nslug: \"healthcare-scan\"\n---\n\n# Healthcare scan\n\n## Skills\n\n- ./skills/healthcare-scan\n- lint.md @teammate@example.com\n\n## Files\n\n- runner <- ~/.claude/runner\n```\n\nUnder **Skills**, a local path (`./\u2026`, `~/\u2026` or `/\u2026`) to a skill folder\nor SKILL.md is pushed to the library and added, with the rest of its folder\nshipped as the skill's files; `<key> @<author email>` adds a teammate's\nlibrary skill. **Files** maps local folders to paths in the pack\n(`.` is the pack root). In skills, point at shipped files relative to the\nskill's folder or with `${CLAUDE_PLUGIN_ROOT}/\u2026`. Applying changes the\ndraft; `--publish` (or `codiedev pack publish`) sends it to the team.\n\n**Just push the file \u2014 we'll figure out where it goes.** Every artifact\nis classified into one of two kinds at upload time:\n\n- **skill** \u2014 the file has SKILL.md frontmatter (`name:` + `description:`\n inside a `---` block). Shows on the Skills page in the portal and is\n invokable as a slash command (`/<name>`).\n- **doc** \u2014 everything else. Lives in the library: list it with\n `codiedev library`, fetch it with `codiedev pull <key>`.\n\nDetection is content-based, not filename-based. The filename prefix\n(`spec-` / `decision-` / `proposal-` / `bugfix-` / `review-` /\n`note-`) is preserved as a *tag* you can filter by, but it never gates\nvisibility. A SKILL-frontmatter file named `note-foo.md` still becomes\na skill.\n\nThe `codiedev push` response always says where the artifact landed \u2014\nread it back to the user so they can confirm.\n\n**Resolving \"the spec we just worked on\":**\n- If a file was recently edited in this session matching the conventions\n above, push that file.\n- If content was drafted inline in the conversation, write it to a file\n first (e.g., `/tmp/spec-xxx.md`) then push.\n\n**Teammate names:** first name usually works (`codiedev ping <name> ...`).\nIf ambiguous, the CLI returns candidates \u2014 retry with the full email.\n\n**Search before pushing.** For any \"save this as \u2026\" request, run\n`codiedev search \"<query>\"` first. If prior art exists, pull it and\niterate rather than duplicating.\n\n**One command for messaging and sharing:** `codiedev ping`. A message\nlands in their inbox and emails them; `--with <key>` also gives them read\naccess (`--edit` for edit). With `--with` and no message it's a silent\nshare. (`codiedev send` / `share` still work as aliases.)\n\n**Errors:**\n- \"not connected\" \u2192 user needs to run `npx codiedev connect` with their\n API token from https://codiedev.com/portal/integrations/claude-code\n- \"ambiguous recipient\" \u2192 surface candidates to the user\n";
147
147
  /** The full Codiedev instructions (team-skill context + command table), for
148
148
  * harnesses Codiedev launches itself (Codie, Codie's pi) rather than a
149
149
  * user-owned instructions file. */
package/dist/utils.js CHANGED
@@ -1674,13 +1674,12 @@ thought, use the \`codiedev\` CLI via Bash:**
1674
1674
  | "push this spec" / "save this as a skill" | \`codiedev push <file.md>\` |
1675
1675
  | "pull X" / "grab the latest spec-X" / "what did a teammate push?" | \`codiedev pull <key>\` |
1676
1676
  | "delete X" / "remove that test push" / "rm spec-old" | \`codiedev delete <key>\` (always confirm with the user first) |
1677
- | "ping a teammate about this" / "ask someone for their take" / "send them this file" | \`codiedev ping <name> "<msg>" [--with <key>] [--file <path>]\` |
1677
+ | "ping a teammate about this" / "send them this spec" / "send them this file" | \`codiedev ping <name> "<msg>" [--with <key>] [--file <path>]\` (\`--with\` also gives them access) |
1678
1678
  | "any messages?" / "check my inbox" / "what did a teammate say?" | \`codiedev inbox\` |
1679
1679
  | "read that reply" / "mark that ping read" | \`codiedev read <ping-id>\` |
1680
1680
  | "reply to that" / "tell them X" (answering a message from \`codiedev inbox\`) | \`codiedev reply <ping-id> "<msg>" [--file <path>]\` (not a new ping: this threads it and marks theirs answered) |
1681
1681
  | "note that X is a follow-up" / "remember X" | \`codiedev note "<text>"\` |
1682
- | "share with a teammate" / "give someone access" (no notification) | \`codiedev share <key> <name> [--role read\\|edit]\` |
1683
- | "send this to a teammate" / "ask someone to look at this" | \`codiedev send <key> <name> ["<msg>"]\` |
1682
+ | "share with a teammate" / "give someone access" (no notification) | \`codiedev ping <name> --with <key> [--edit]\` (no message = silent share) |
1684
1683
  | "find something about X" / "has anyone solved Y?" | \`codiedev search "<query>" [--limit N]\` |
1685
1684
  | "show my library" / "what artifacts exist?" | \`codiedev library [--scope mine\\|shared\\|all] [--kind doc\\|skill]\` |
1686
1685
  | "run my agent's test cases" / "check the dataset on model Y" / "run v2 of the dataset" | \`codiedev traces cases <agent> [--dataset <name> [--version <n>]] [--model <id>]\` (writes cases + RUN_CASES.md + results.json; follow it, then \`codiedev traces report <results.json>\`) |
@@ -1756,9 +1755,10 @@ If ambiguous, the CLI returns candidates — retry with the full email.
1756
1755
  \`codiedev search "<query>"\` first. If prior art exists, pull it and
1757
1756
  iterate rather than duplicating.
1758
1757
 
1759
- **Sharing vs sending:** \`codiedev share\` is silent (access only, no
1760
- notification). \`codiedev send\` both grants access AND pings the
1761
- recipient. Use send when the user is actively looping someone in.
1758
+ **One command for messaging and sharing:** \`codiedev ping\`. A message
1759
+ lands in their inbox and emails them; \`--with <key>\` also gives them read
1760
+ access (\`--edit\` for edit). With \`--with\` and no message it's a silent
1761
+ share. (\`codiedev send\` / \`share\` still work as aliases.)
1762
1762
 
1763
1763
  **Errors:**
1764
1764
  - "not connected" → user needs to run \`npx codiedev connect\` with their
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codiedev",
3
- "version": "0.9.88",
3
+ "version": "0.9.89",
4
4
  "description": "Connect Claude Code, Codex, Cursor, OpenCode, or VS Code Copilot to Codiedev for team session capture and artifact collaboration — and run the governed Codie harness",
5
5
  "bin": {
6
6
  "codiedev": "dist/cli.js",