ente-cli 0.4.62 → 0.4.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -131,7 +131,7 @@ Every command supports `--json`. Run `ente --help` or `ente <group> --help`.
131
131
  |---|---|
132
132
  | `auth` | `pair`, `login`, `status`, `logout`, `profiles` |
133
133
  | `entity` | `list`, `create`, `get`, `update` (`--name`, `--tag`, `--description`), `rename`, `archive`, `restore` (`--share-parents` plus the returned grant fingerprint), `pin` (`--role`, optional confirmed parent grants), `unpin`, `add-to-space`, `remove-from-space` (`--remove-from-activities` optional) |
134
- | `activity` | `list`, `create`, `search`, `get`, `update`, `delete`, `restore`, `message add`, `attachment upload` |
134
+ | `activity` | `list`, `create`, `search`, `get`, `transcript` (`--grep`, `--context`), `update`, `delete`, `restore`, `message add`, `attachment upload` |
135
135
  | `agenda` | `create-point`, `link-task` |
136
136
  | `task` | `list`, `get`, `create`, `update`, `done`, `assign`, `unassign`, `set-assignees`, `clear-assignees` |
137
137
  | `pins` | `list` |
package/dist/SKILL.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: m:ente-cli
3
3
  description: "Cli: drives the ente CRM and knowledge graph over its Convex API as the signed-in user — entities (people, organisations, projects, topics, places, objects), activities (notes, calls, meetings, tasks), relationships, spaces, full-text and AI-backed search, agent threads and mail, plus Excalidraw canvas prototypes. Use when context about a person, an organisation or a meeting has to be stored, looked up or updated from the shell. Not for splitting shared costs, which is schnorrer-cli."
4
- when_to_use: "Remembering what was said in a call or meeting; looking up open tasks, deadlines or follow-ups for a person or project; creating or renaming an entity and pinning it to a parent; linking an activity to several entities or moving it between spaces; asking a question over the whole graph and getting citations; reviewing the voice-recording prompt or debugging a failed recording; sending a notification mail or an agent-inbox reply; posting to the in-app feedback board; managing Excalidraw canvas HTML prototypes on an entity board."
4
+ when_to_use: "Remembering what was said in a call or meeting, including reading or searching the transcript of the recording behind an activity; looking up open tasks, deadlines or follow-ups for a person or project; creating or renaming an entity and pinning it to a parent; linking an activity to several entities or moving it between spaces; asking a question over the whole graph and getting citations; reviewing the voice-recording prompt or debugging a failed recording; sending a notification mail or an agent-inbox reply; posting to the in-app feedback board; managing Excalidraw canvas HTML prototypes on an entity board."
5
5
  metadata:
6
6
  short-description: Relationship memory through ente
7
7
  ---
@@ -132,6 +132,7 @@ ente activity list [--entity "Jane"] [--type note|conversation|meeting|call|mess
132
132
  ente activity create --type meeting --title "Call with Jane" --entity "Jane Doe" --entity "Acme Corp" --space "Work" [--content "…"] [--content-file ./notes.md] [--auto-link --entity-space-grant-fingerprint <token>] [--json]
133
133
  ente activity search "quarterly review" [--entity "Acme"] [--type meeting] [--limit 10] [--json]
134
134
  ente activity get <activityId> [--json] # complete detail: body, full nested agenda, messages/replies, entities, attachments
135
+ ente activity transcript <activityId> [--grep "Preis"] [--context 2] [--recording <id>] [--json] # transcript of the recording behind it
135
136
  ente activity update <activityId> [--title "…"] [--content "…"] [--entity-add "Bob"] [--entity-remove "Carol"] [--agent-assignee <agentId> ... | --clear-agent-assignees] [--json]
136
137
  ente activity content read <activityId> [--cursor <cursor> --expected-version <version>] [--max-blocks 20] [--max-characters 12000] [--json]
137
138
  ente activity content edit <activityId> --expected-version <version> --operations-file ./operations.json [--json]
@@ -285,6 +286,32 @@ board is already dense. The create result includes `reviewPath`. Update and dele
285
286
  read and fail on a concurrent human edit. These remote scene changes sync into open boards, but do
286
287
  not enter another browser's local undo stack.
287
288
 
289
+ ### Recording transcripts — check them when something is unclear
290
+
291
+ Activities, notes and summaries made from a recording keep only what the
292
+ recording agent chose to keep. **When a note, summary, task or meeting record is
293
+ unclear, contradictory or lacks a detail you need (an amount, a date, who said
294
+ what, the reason for a decision), deliberately read the transcript before you
295
+ answer or act** — do not guess from the summary.
296
+
297
+ ```bash
298
+ ente activity transcript <activityId> # every recording that created or changed it, full transcript
299
+ ente activity transcript <activityId> --grep "Rechnung" --context 3 # only the passages around a term
300
+ ```
301
+
302
+ - Finds recordings through the agent runs that created or changed the activity; an
303
+ activity made by hand, or by a recording processed outside Ente, has none.
304
+ - Your own recordings are readable as long as what they wrote lies in spaces your
305
+ agent key may read. Another member's recording is readable only when
306
+ **everything it wrote** (activities, entities, agenda points, pins) lies in spaces
307
+ you are a member of and your agent key may read; mail, calendar or space-move
308
+ tools withhold it. Otherwise
309
+ it is listed with the reason (`outside_reader_spaces`, `untraceable_tool` for mail,
310
+ calendar or space moves, `processing`, …) and no text.
311
+ - `--grep` matches case-insensitively by sentence or line. `--json` returns per
312
+ recording either `transcript`, or with `--grep` `transcript: null` plus `matches`
313
+ (lists of passages). At most the 5 newest recordings are listed.
314
+
288
315
  ### Recording (voice) pipeline
289
316
 
290
317
  ```bash
@@ -371,6 +398,7 @@ ente feedback status <feedbackId> <status> # move to a board colum
371
398
  5. **Operate** — entity/activity/task CRUD (prefer `--json` for parsing).
372
399
  6. **Link precisely** — link independently central entities, prefer specific children, and omit ancestors that are implied by hierarchy.
373
400
  7. **Confirm** — re-run the relevant list/get after writes to verify.
401
+ 8. **Unclear? Read the source** — if an activity from a recording leaves a question open, run `ente activity transcript <activityId> --grep <term>` before answering.
374
402
 
375
403
  ---
376
404
 
package/dist/cli.mjs CHANGED
@@ -3711,7 +3711,7 @@ function warn(opts, latest) {
3711
3711
  }
3712
3712
 
3713
3713
  // ente/version.ts
3714
- var VERSION = "0.4.62";
3714
+ var VERSION = "0.4.64";
3715
3715
 
3716
3716
  // ente/branding.ts
3717
3717
  var NPM_REGISTRY = "https://registry.npmjs.org";
@@ -13013,6 +13013,97 @@ var ACTIVITY_COMMANDS = [
13013
13013
  ActivityAttachmentUpload
13014
13014
  ];
13015
13015
 
13016
+ // ente/commands/activityTranscript.ts
13017
+ var listForActivity = makeFunctionReference(
13018
+ "recordingTranscripts:listForActivity"
13019
+ );
13020
+ var getForActivity = makeFunctionReference("recordingTranscripts:getForActivity");
13021
+ var WITHHELD_TEXT = {
13022
+ processing: "still being processed",
13023
+ external_recipient: "processed by an external recipient, so its writes cannot be traced",
13024
+ no_traceable_writes: "its writes cannot be traced",
13025
+ untraceable_tool: "it used a tool whose effect cannot be traced",
13026
+ outside_reader_spaces: "it also wrote into spaces you are not a member of",
13027
+ too_large: "too many runs or messages to check"
13028
+ };
13029
+ function transcriptPassages(transcript) {
13030
+ return transcript.split(/\n+|(?<=[.!?])\s+/u).map((passage) => passage.trim()).filter((passage) => passage.length > 0);
13031
+ }
13032
+ function grepTranscript(transcript, term, context) {
13033
+ const passages = transcriptPassages(transcript);
13034
+ const needle = term.toLocaleLowerCase();
13035
+ const windows = [];
13036
+ passages.forEach((passage, index) => {
13037
+ if (!passage.toLocaleLowerCase().includes(needle)) return;
13038
+ const start = Math.max(0, index - context);
13039
+ const end = Math.min(passages.length - 1, index + context);
13040
+ const last = windows.at(-1);
13041
+ if (last && start <= last[1] + 1) last[1] = end;
13042
+ else windows.push([start, end]);
13043
+ });
13044
+ return windows.map(([start, end]) => passages.slice(start, end + 1));
13045
+ }
13046
+ function heading(summary) {
13047
+ const date = new Date(summary.createdAt).toLocaleString("de-DE", { timeZone: "Europe/Berlin" });
13048
+ const who = summary.own ? "you" : summary.createdByName ?? "another member";
13049
+ return `Recording ${summary.recordingId} \xB7 ${summary.title ?? "untitled"} \xB7 ${date} \xB7 by ${who} \xB7 ${summary.operations.join("/")} this activity`;
13050
+ }
13051
+ var ActivityTranscript = class extends ProfileCommand {
13052
+ static paths = [["activity", "transcript"]];
13053
+ static usage = Command.Usage({
13054
+ category: "Activity",
13055
+ description: "Read or search the transcript of the recording behind an activity",
13056
+ details: `
13057
+ Lists the recordings whose processing created or changed the activity and prints their
13058
+ transcripts. Use it whenever a note, summary or task is unclear or lacks detail: the
13059
+ transcript holds what the recording agent left out.
13060
+
13061
+ You can read your own recordings within the spaces your agent key may read. Another
13062
+ member's recording is readable only when everything it wrote is in spaces you are a
13063
+ member of; otherwise it is listed with the reason, without title or text.
13064
+ `,
13065
+ examples: [
13066
+ ["Print the transcript", "ente activity transcript <activityId>"],
13067
+ ["Find what was said about a price", "ente activity transcript <activityId> --grep Preis --context 3"]
13068
+ ]
13069
+ });
13070
+ activityId = options_exports.String({ required: true, name: "activityId" });
13071
+ recording = options_exports.String("--recording", { description: "Only this recording ID" });
13072
+ grep = options_exports.String("--grep", { description: "Print only passages containing this text (case-insensitive)" });
13073
+ contextPassages = options_exports.String("--context", "2", { description: "Passages around each --grep hit (default 2)" });
13074
+ async run() {
13075
+ const context = Number(this.contextPassages);
13076
+ if (!/^\d+$/u.test(this.contextPassages)) throw new Error("--context must be a whole number \u2265 0");
13077
+ if (this.grep !== void 0 && this.grep.trim() === "") throw new Error("--grep needs a search term");
13078
+ const caller = await resolveCaller();
13079
+ const summaries = (await caller.query(listForActivity, { activityId: this.activityId })).filter((summary) => !this.recording || summary.recordingId === this.recording);
13080
+ if (this.recording && summaries.length === 0) {
13081
+ throw new Error(`Recording ${this.recording} did not create or change activity ${this.activityId}`);
13082
+ }
13083
+ const results = [];
13084
+ for (const summary of summaries) {
13085
+ const transcript = summary.readable ? (await caller.query(getForActivity, { activityId: this.activityId, recordingId: summary.recordingId })).transcript : null;
13086
+ const matches = transcript !== null && this.grep !== void 0 ? grepTranscript(transcript, this.grep, context) : void 0;
13087
+ results.push({ ...summary, transcript: matches === void 0 ? transcript : null, ...matches ? { matches } : {} });
13088
+ }
13089
+ this.emitText({ data: results }, () => {
13090
+ if (results.length === 0) return "No recording created or changed this activity.";
13091
+ return results.map((result) => {
13092
+ const lines = [heading(result)];
13093
+ if (!result.readable) {
13094
+ lines.push(`Transcript withheld: ${WITHHELD_TEXT[result.withheldReason ?? "no_traceable_writes"]}${result.withheldDetail ? ` (${result.withheldDetail})` : ""}.`);
13095
+ } else if (result.matches) {
13096
+ lines.push(result.matches.length === 0 ? `No passage mentions "${this.grep}".` : result.matches.map((passages) => passages.join(" ")).join("\n\u2026\n"));
13097
+ } else {
13098
+ lines.push(result.transcript ?? "No transcript yet.");
13099
+ }
13100
+ return lines.join("\n");
13101
+ }).join("\n\n");
13102
+ });
13103
+ }
13104
+ };
13105
+ var ACTIVITY_TRANSCRIPT_COMMANDS = [ActivityTranscript];
13106
+
13016
13107
  // ente/deadline.ts
13017
13108
  var DEFAULT_HOUR = 22;
13018
13109
  var DEFAULT_MINUTE = 0;
@@ -15758,6 +15849,7 @@ Commands:
15758
15849
  ente notification send Email your own Ente account (text, HTML, and images)
15759
15850
  ente activity create|list|get|update|delete|restore
15760
15851
  ente activity content read|edit
15852
+ ente activity transcript <activityId> [--grep <text>] Transcript behind an activity \u2014 read it when a note or summary is unclear
15761
15853
  ente agenda create-point|link-task
15762
15854
  ente activity message add <activityId> --content "..."
15763
15855
  ente activity attachment upload <activityId> <file>
@@ -16837,6 +16929,7 @@ for (const Cmd of [
16837
16929
  ...AUTH_COMMANDS,
16838
16930
  ...ENTITY_COMMANDS,
16839
16931
  ...ACTIVITY_COMMANDS,
16932
+ ...ACTIVITY_TRANSCRIPT_COMMANDS,
16840
16933
  ...TASK_COMMANDS,
16841
16934
  ...LIST_COMMANDS,
16842
16935
  ...USERS_COMMANDS,