ente-cli 0.4.77 → 0.4.79

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
@@ -107,8 +107,9 @@ ente entity rename "Lorey Georg" "Georg Lorey"
107
107
  ente task list --due today
108
108
  ente activity create --type note --title "Meeting notes" --entity "Alice" --space "Personal"
109
109
  ente activity get <activityId> --json # includes the body, nested agenda, messages/replies, entities, and attachments
110
- ente agenda create-point --meeting <meetingActivityId> --title "Decisions" --content="- Ship the smaller scope"
110
+ ente agenda create-point --activity <activityId> --title "Decisions" --content="- Ship the smaller scope"
111
111
  ente agenda link-task --point <agendaPointId> --task "#12"
112
+ # Agendas work on every activity type; --meeting remains an alias for --activity.
112
113
  ente activity message add <activityId> --content "Decision: ship the smaller scope first."
113
114
  ente activity content read <activityId> --json
114
115
  ente activity content edit <activityId> --expected-version 42 --operations-file edits.json --json
@@ -446,3 +447,17 @@ Use the external operator command. Whole-history panel sharing does not grant
446
447
  access to diagnostics, and diagnostic reads do not append to chat history.
447
448
 
448
449
  Identify your connection with `ente agent set-icon fish` (or `--reset`), then find its icon in `/agents`. Requires write scope and always targets your own bound agent.
450
+
451
+
452
+ Raw evidence retrieval supports `ente query "question" --mode hybrid --json` and
453
+ `--mode semantic`. Omitted/lexical mode keeps deterministic retrieval without
454
+ provider calls. Hybrid preserves typed structured evidence; semantic is indexed
455
+ own Personal activity passages only. Both return evidence without an answer.
456
+ Inspect execution, coverage, fallback and truncation metadata; vector ranks are
457
+ not answer confidence. Semantic availability requires the separate default-off
458
+ Personal retrieval pilot, not an Ask synthesis slot. See `ente guide activity` and
459
+ the shipped skill for scope and citation details.
460
+
461
+ Explicit vector modes report the selected provider, model, region, embedding identity and generation in `retrieval.vector`. Optional OpenAI embeddings use `text-embedding-3-small` at 512 dimensions. A provider/model/region change requires renewed account consent and a new empty generation; it does not select history or future activities. No automatic provider fallback runs. Omitted/lexical query remains zero-egress.
462
+
463
+ Hybrid ordering uses RRF plus semantic branch coverage. Returned rank is authoritative; scores are not calibrated confidence or a pure sort contract.
package/dist/SKILL.md CHANGED
@@ -150,6 +150,9 @@ ente auth logout
150
150
  ente auth profiles
151
151
 
152
152
  # Search & ask
153
+ # Ask keeps scoped evidence on synthesis failure; check synthesisStatus.
154
+ # Optional sourceHash/sourceFingerprint/passage metadata binds citations to a source version.
155
+ # query remains deterministic and never starts embedding/indexing. See guide ask-the-graph.
153
156
  ente search "Alice" [--type person] [--json]
154
157
  ente ask "What's open with Erik?" [--space <name>] [--entity <name>] [--evidence] [--json] # AI answer + citations
155
158
  ente query "QM system export" [--space <name>] [--entity <name>] [--since <epoch-ms>] [--until <epoch-ms>] [--limit 12] [--verbose] [--json] # evidence only, no AI
@@ -184,8 +187,9 @@ ente activity attachment upload <activityId> ./file.pdf [--name "Contract.pdf"]
184
187
  ente activity delete <activityId> [--json]
185
188
  ente activity restore <activityId> [--json]
186
189
 
187
- # Meeting agendas
188
- ente agenda create-point --meeting <meetingActivityId> --title "Decisions" [--content="…"] [--content-file ./decisions.md] [--parent <agendaPointId>] [--after <agendaPointId>] [--json]
190
+ # Activity agendas (all activity types)
191
+ # --meeting remains a compatibility alias for --activity.
192
+ ente agenda create-point --activity <activityId> --title "Decisions" [--content="…"] [--content-file ./decisions.md] [--parent <agendaPointId>] [--after <agendaPointId>] [--json]
189
193
  ente agenda link-task --point <agendaPointId> --task <activityId|#N> [--json]
190
194
 
191
195
  # Excalidraw Canvas HTML prototypes
@@ -623,3 +627,32 @@ icon, then find it in `/agents`. Use `ente agent set-icon --reset` to restore th
623
627
  default. Run `ente agent set-icon --help` for curated IDs. Write scope is required;
624
628
  there is no agent-ID option. Connections shows last recorded external access,
625
629
  which can have historical gaps and excludes hosted/scheduled activity.
630
+
631
+
632
+ ### Raw retrieval modes
633
+
634
+ `ente query "question" --json` keeps deterministic entity, activity title/body,
635
+ task and relationship retrieval without provider calls. `--mode lexical` is the
636
+ same default. Keep `ente search` for fuzzy entity lookup and `ente activity search`
637
+ for ordinary title/body keyword search.
638
+
639
+ Use `ente query "question" --mode hybrid --space Personal --json` only when semantic
640
+ retrieval is wanted and consented. Hybrid retains typed deterministic structured
641
+ results and combines lexical/vector activity passages. `--mode semantic` returns
642
+ vector activity passages only, for inspection/comparison. Initial vectors cover
643
+ only the caller's own Personal notes, conversations, meetings and calls. Related
644
+ entity IDs/names are authorized context, not semantic entity matches.
645
+
646
+ Neither mode generates an answer or needs an Ask synthesis slot. Read
647
+ `retrieval.requestedMode`, `usedMode`, `status`, `vector`, `coverage`, `counts` and
648
+ `truncation`. Hybrid may explicitly fall back to lexical. Unavailable semantic
649
+ returns no evidence and exits1. Counts describe bounded candidates, not complete
650
+ account totals; original lexical truncation flags still apply. Vector ranks are
651
+ not answer confidence. Use source hashes, passage offsets and sourceUrl to check
652
+ an activity revision before citing it. Indexing remains default off; future
653
+ activity opt-in and reviewed historical selection are independent. Own-model
654
+ accounts do not send data to the hosted embedding pilot.
655
+
656
+ Explicit vector modes report the selected provider, model, region, embedding identity and generation in `retrieval.vector`. Optional OpenAI embeddings use `text-embedding-3-small` at 512 dimensions. A provider/model/region change requires renewed account consent and a new empty generation; it does not select history or future activities. No automatic provider fallback runs. Omitted/lexical query remains zero-egress.
657
+
658
+ Hybrid ranking uses RRF plus early semantic branch coverage. Use returned `rank` for order; numeric scores are neither a pure sort contract nor calibrated confidence.
package/dist/cli.mjs CHANGED
@@ -3800,7 +3800,7 @@ async function runCli(cli2, argv, context) {
3800
3800
  }
3801
3801
 
3802
3802
  // ente/version.ts
3803
- var VERSION = "0.4.77";
3803
+ var VERSION = "0.4.79";
3804
3804
 
3805
3805
  // ente/branding.ts
3806
3806
  var NPM_REGISTRY = "https://registry.npmjs.org";
@@ -4246,7 +4246,7 @@ var EnteClient = class _EnteClient {
4246
4246
  ...spaceId ? { spaceId } : {}
4247
4247
  });
4248
4248
  }
4249
- // --- meeting agendas ---------------------------------------------------
4249
+ // --- activity agendas ---------------------------------------------------
4250
4250
  createAgendaPoint(body) {
4251
4251
  return this.rest.post("/api/external/agenda-points", body);
4252
4252
  }
@@ -14604,7 +14604,8 @@ function parseIntFlag(flag, raw, min) {
14604
14604
  // ente/commands/ask.ts
14605
14605
  var askActionRun = makeFunctionReference("askAction:run");
14606
14606
  function formatCitation(c) {
14607
- return `[${c.evidenceId ?? ""}] ${c.kind ?? ""}: ${c.title ?? ""}`.trim();
14607
+ const passage = c.passage ? ` (chars ${c.passage.start}\u2013${c.passage.end}; ${c.passage.sourceHash.slice(0, 12)})` : "";
14608
+ return `[${c.evidenceId ?? ""}] ${c.kind ?? ""}: ${c.title ?? ""}${passage}`.trim();
14608
14609
  }
14609
14610
  function formatAskResult(data, includeEvidence) {
14610
14611
  const lines = [data.answer ?? ""];
@@ -14627,6 +14628,7 @@ function formatAskResult(data, includeEvidence) {
14627
14628
  for (const item of evidence) {
14628
14629
  lines.push(`- [${item.id ?? ""}] ${item.kind ?? ""}: ${item.title ?? ""}`);
14629
14630
  if (item.text) lines.push(` ${item.text}`);
14631
+ if (item.metadataText) lines.push(` ${item.metadataText}`);
14630
14632
  }
14631
14633
  }
14632
14634
  }
@@ -14654,8 +14656,16 @@ var AskCmd = class extends ProfileCommand {
14654
14656
  };
14655
14657
  var ASK_COMMANDS = [AskCmd];
14656
14658
 
14659
+ // ente/queryModes.ts
14660
+ var QUERY_MODES = ["lexical", "semantic", "hybrid"];
14661
+
14657
14662
  // ente/commands/query.ts
14658
14663
  var askQuery = makeFunctionReference("ask:query");
14664
+ var rawQuery = makeFunctionReference("retrieval/raw:run");
14665
+ async function retrieveEvidenceC(caller, body, mode) {
14666
+ if (mode !== void 0 && !QUERY_MODES.includes(mode)) throw new Error("--mode must be lexical, hybrid or semantic");
14667
+ return mode === "hybrid" || mode === "semantic" ? caller.action(rawQuery, { ...body, mode }) : caller.query(askQuery, body);
14668
+ }
14659
14669
  function formatEvidence(item, verbose) {
14660
14670
  const lines = [`[${item.id ?? ""}] ${item.kind ?? ""}: ${item.title ?? ""}`];
14661
14671
  const details = [];
@@ -14670,8 +14680,12 @@ function formatEvidence(item, verbose) {
14670
14680
  }
14671
14681
  function formatQueryResult(data, verbose) {
14672
14682
  const evidence = data.evidence ?? [];
14673
- if (evidence.length === 0) return "No evidence found.";
14674
14683
  const lines = [];
14684
+ if (data.retrieval && data.retrieval.requestedMode !== "lexical") {
14685
+ const retrieval = data.retrieval;
14686
+ lines.push(`Retrieval: ${retrieval.requestedMode} \u2192 ${retrieval.usedMode}; vectors ${retrieval.vector.searchExecuted ? retrieval.vector.provider : "not executed"}${retrieval.fallbackReason ? ` (${retrieval.fallbackReason})` : ""}`);
14687
+ }
14688
+ if (!evidence.length) lines.push("No evidence found.");
14675
14689
  for (const item of evidence) lines.push(...formatEvidence(item, verbose));
14676
14690
  const warnings = data.warnings ?? [];
14677
14691
  if (warnings.length) {
@@ -14682,10 +14696,11 @@ function formatQueryResult(data, verbose) {
14682
14696
  var QueryCmd = class extends ProfileCommand {
14683
14697
  static paths = [["query"]];
14684
14698
  static usage = Command.Usage({
14685
- category: "Ask",
14686
- description: "Run ente's deterministic evidence retrieval without AI synthesis"
14699
+ category: "Retrieval",
14700
+ description: "Retrieve raw evidence; default lexical, optional hybrid or semantic activity passages"
14687
14701
  });
14688
14702
  question = options_exports.String();
14703
+ mode = options_exports.String("--mode", { description: "lexical (default, no provider calls), hybrid, or semantic (own Personal activity passages only)" });
14689
14704
  space = options_exports.String("--space", { description: "Restrict evidence to a space (name or ID)" });
14690
14705
  entity = options_exports.String("--entity", { description: "Use an entity (name or ID) as the main graph anchor" });
14691
14706
  limit = options_exports.String("--limit", { description: "Maximum evidence items to return" });
@@ -14693,10 +14708,12 @@ var QueryCmd = class extends ProfileCommand {
14693
14708
  until = options_exports.String("--until", { description: "Only include activity evidence before this epoch ms" });
14694
14709
  verbose = options_exports.Boolean("--verbose,-v", false, { description: "Print full evidence snippets" });
14695
14710
  async run() {
14711
+ if (this.mode !== void 0 && !QUERY_MODES.includes(this.mode)) throw new Error("--mode must be lexical, hybrid or semantic");
14696
14712
  const caller = await resolveCaller();
14697
14713
  const body = await buildEvidenceBodyC(caller, this);
14698
- const res = await caller.query(askQuery, body);
14714
+ const res = await retrieveEvidenceC(caller, body, this.mode);
14699
14715
  this.emitText({ data: res }, () => formatQueryResult(res, this.verbose));
14716
+ if (res.retrieval?.status === "unavailable") return 1;
14700
14717
  }
14701
14718
  };
14702
14719
  var QUERY_COMMANDS = [QueryCmd];
@@ -15742,12 +15759,12 @@ import { readFileSync as readFileSync12 } from "node:fs";
15742
15759
  var AgendaPointCreate = class extends ClientCommand {
15743
15760
  static paths = [["agenda", "create-point"]];
15744
15761
  static usage = Command.Usage({
15745
- category: "Meeting agenda",
15762
+ category: "Activity agenda",
15746
15763
  description: "Create a titled agenda point with optional markdown content"
15747
15764
  });
15748
- meeting = options_exports.String("--meeting", {
15765
+ activity = options_exports.String("--activity,--meeting", {
15749
15766
  required: true,
15750
- description: "Meeting activity ID"
15767
+ description: "Activity ID of any type (--meeting is a compatibility alias)"
15751
15768
  });
15752
15769
  title = options_exports.String("--title", {
15753
15770
  required: true,
@@ -15770,7 +15787,7 @@ var AgendaPointCreate = class extends ClientCommand {
15770
15787
  throw new Error("Use either --content or --content-file, not both.");
15771
15788
  const contentMarkdown = this.content !== void 0 ? this.content : this.contentFile !== void 0 ? readFileSync12(this.contentFile, "utf8") : void 0;
15772
15789
  const result = await this.client().createAgendaPoint({
15773
- meetingActivityId: this.meeting,
15790
+ meetingActivityId: this.activity,
15774
15791
  title: this.title,
15775
15792
  contentMarkdown,
15776
15793
  parentPointId: this.parent,
@@ -15783,7 +15800,7 @@ var AgendaPointCreate = class extends ClientCommand {
15783
15800
  var agendaPointDocumentId = (pointId) => `agenda-point:${pointId}`;
15784
15801
  var AgendaHtmlList = class extends ProfileCommand {
15785
15802
  static paths = [["agenda", "html", "list"]];
15786
- static usage = Command.Usage({ category: "Meeting agenda", description: "List interactive HTML blocks in an agenda point" });
15803
+ static usage = Command.Usage({ category: "Activity agenda", description: "List interactive HTML blocks in an agenda point" });
15787
15804
  pointId = options_exports.String();
15788
15805
  async run() {
15789
15806
  const caller = await resolveCaller();
@@ -15794,7 +15811,7 @@ var AgendaHtmlList = class extends ProfileCommand {
15794
15811
  };
15795
15812
  var AgendaHtmlGet = class extends ProfileCommand {
15796
15813
  static paths = [["agenda", "html", "get"]];
15797
- static usage = Command.Usage({ category: "Meeting agenda", description: "Read one agenda-point HTML block including source" });
15814
+ static usage = Command.Usage({ category: "Activity agenda", description: "Read one agenda-point HTML block including source" });
15798
15815
  pointId = options_exports.String();
15799
15816
  blockId = options_exports.String();
15800
15817
  async run() {
@@ -15807,7 +15824,7 @@ var AgendaHtmlGet = class extends ProfileCommand {
15807
15824
  };
15808
15825
  var AgendaHtmlAdd = class extends ProfileCommand {
15809
15826
  static paths = [["agenda", "html", "add"]];
15810
- static usage = Command.Usage({ category: "Meeting agenda", description: "Append an interactive HTML block to an agenda point" });
15827
+ static usage = Command.Usage({ category: "Activity agenda", description: "Append an interactive HTML block to an agenda point" });
15811
15828
  pointId = options_exports.String();
15812
15829
  htmlFile = options_exports.String({ required: false, name: "htmlFile" });
15813
15830
  htmlFileFlag = options_exports.String("--html-file", { description: "Read HTML from a file; use - or omit for stdin" });
@@ -15832,7 +15849,7 @@ var AgendaHtmlAdd = class extends ProfileCommand {
15832
15849
  };
15833
15850
  var AgendaHtmlUpdate = class extends ProfileCommand {
15834
15851
  static paths = [["agenda", "html", "update"]];
15835
- static usage = Command.Usage({ category: "Meeting agenda", description: "Surgically update one agenda-point HTML block" });
15852
+ static usage = Command.Usage({ category: "Activity agenda", description: "Surgically update one agenda-point HTML block" });
15836
15853
  pointId = options_exports.String();
15837
15854
  blockId = options_exports.String();
15838
15855
  htmlFile = options_exports.String("--html-file", { description: "Read HTML from a file; use - for stdin" });
@@ -16108,7 +16125,7 @@ ancestors redundantly.
16108
16125
  Commands:
16109
16126
  ente search <query> Fuzzy search entities
16110
16127
  ente ask <question> Natural-language answer (AI synthesis + citations)
16111
- ente query <question> Deterministic evidence retrieval (no synthesis)
16128
+ ente query <question> Raw evidence; default lexical, optional --mode hybrid|semantic
16112
16129
  ente entity create|get|update|duplicate|rename|archive|restore|pin|unpin
16113
16130
  ente entity list [--archived]
16114
16131
  ente pins list <entity> List pins for an entity
@@ -16225,12 +16242,12 @@ Creating activities:
16225
16242
  --entity "Erik Stahl" --entity "Preclinics" --space "Preclinics" \\
16226
16243
  --content "Discussed QM system. Follow up on export feature."
16227
16244
 
16228
- Meeting agendas:
16245
+ Activity agendas (all activity types; --meeting remains an alias):
16229
16246
  ente activity create --type meeting --title "QM system review" ...
16230
- ente agenda create-point --meeting <meeting-id> --title "Rollout" --content="- Decision ..."
16247
+ ente agenda create-point --activity <activity-id> --title "Rollout" --content="- Decision ..."
16231
16248
  ente agenda link-task --point <point-id> --task "#12"
16232
16249
 
16233
- Prefer agenda points for structured meeting content when they add useful
16250
+ Prefer agenda points for structured activity content when they add useful
16234
16251
  topic structure. Link meeting-derived tasks to the point they came from.
16235
16252
 
16236
16253
  Golden rule:
@@ -16265,7 +16282,7 @@ Archiving (trash):
16265
16282
  content: `Resolve entities globally first: ente search "Apollo" --json
16266
16283
  Use an explicit space when the task specifies one:
16267
16284
  ente query "launch decisions" --space "Work" --entity "Apollo" --since 1791763200000 --until 1792368000000 --limit 8 --json
16268
- Time filters apply to activity evidence; query uses no model.
16285
+ Time filters apply to activity evidence. Default/lexical query uses no provider. Explicit hybrid uses the separately consented embedding provider; semantic returns indexed own Personal activity passages only. Neither mode generates an answer. Inspect requested/used mode, vector execution, coverage, truncation and fallback in --json output. Vector metadata also names provider/model/region and index generation. Optional OpenAI text-embedding-3-small uses 512 dimensions. A provider/model/region change needs renewed consent and an empty generation; future/history must be selected again. No automatic provider fallback runs. Hybrid uses RRF plus semantic branch coverage: rank is authoritative, not a pure score sort or calibrated confidence.
16269
16286
 
16270
16287
  Read one compact entity-history page:
16271
16288
  ente activity list --entity <id> --after 1791763200000 --min-count 0 --limit 10 --compact --json
@@ -16305,7 +16322,7 @@ Tips:
16305
16322
  1. ente search "person name" # find entity, check pins
16306
16323
  2. ente activity create --type meeting --title "..." \\
16307
16324
  --entity "person" --entity "their org" --space "..."
16308
- 3. ente agenda create-point --meeting <meeting-id> --title "..." --content="..."
16325
+ 3. ente agenda create-point --activity <activity-id> --title "..." --content="..."
16309
16326
  4. If follow-ups: create each task, then:
16310
16327
  ente agenda link-task --point <point-id> --task <task-id|#N>
16311
16328