@great-arrow/cli 0.7.0 → 0.7.1

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
@@ -80,6 +80,12 @@ gad memory delete <id>
80
80
  cat notes.md | gad memory create --title "Meeting notes"
81
81
  ```
82
82
 
83
+ `gad memory search` shows a **Source** column for every hit: the original
84
+ document's link (GitHub, Notion, Drive…) when there is one, otherwise the
85
+ memory's page in the web app. `gad ask` prints a numbered **Sources** list of
86
+ the memories its answer was built from, under the answer (`--quiet` hides it;
87
+ `--json` keeps the raw `hits`).
88
+
83
89
  ### Workspace
84
90
 
85
91
  ```bash
package/dist/index.js CHANGED
@@ -9483,7 +9483,7 @@ function isNodeError(value) {
9483
9483
 
9484
9484
  // src/lib/version.ts
9485
9485
  var CLI_PACKAGE_NAME = "@great-arrow/cli";
9486
- var CLI_VERSION = "0.7.0";
9486
+ var CLI_VERSION = "0.7.1";
9487
9487
  var GAD_INSTALL_VERSION = "2026.08.08";
9488
9488
  var GAD_INSTALL_MIN_VERSION = "2026.06.22";
9489
9489
  var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
@@ -12198,11 +12198,56 @@ function readStdin(stream) {
12198
12198
  return readStream(input2);
12199
12199
  }
12200
12200
 
12201
+ // src/lib/sources.ts
12202
+ function nonEmpty2(value) {
12203
+ if (typeof value !== "string") return null;
12204
+ const clean = stripControlChars(value).trim();
12205
+ return clean === "" ? null : clean;
12206
+ }
12207
+ function httpUrl(value) {
12208
+ const raw = nonEmpty2(value);
12209
+ if (!raw) return null;
12210
+ try {
12211
+ const parsed = new URL(raw);
12212
+ return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.toString() : null;
12213
+ } catch {
12214
+ return null;
12215
+ }
12216
+ }
12217
+ function sourceOf(hit, apiUrl) {
12218
+ const memoryId = nonEmpty2(hit.memoryId);
12219
+ const link = httpUrl(hit.url) ?? (memoryId ? `${apiUrl.replace(/\/$/, "")}/stuff/memories/${encodeURIComponent(memoryId)}` : null);
12220
+ const label = nonEmpty2(hit.fileName) ?? nonEmpty2(hit.memoryTitle) ?? nonEmpty2(hit.title) ?? memoryId ?? "Untitled";
12221
+ return { label, link };
12222
+ }
12223
+ function uniqueSources(hits, apiUrl, max = 5) {
12224
+ const seen = /* @__PURE__ */ new Set();
12225
+ const out2 = [];
12226
+ for (const hit of hits) {
12227
+ const source = sourceOf(hit, apiUrl);
12228
+ const key = source.link ?? source.label;
12229
+ if (seen.has(key)) continue;
12230
+ seen.add(key);
12231
+ out2.push(source);
12232
+ if (out2.length >= max) break;
12233
+ }
12234
+ return out2;
12235
+ }
12236
+ function formatSources(sources) {
12237
+ if (sources.length === 0) return "";
12238
+ const lines = sources.map(
12239
+ (s2, i) => ` [${i + 1}] ${s2.label}${s2.link ? ` \u2014 ${s2.link}` : ""}`
12240
+ );
12241
+ return `Sources:
12242
+ ${lines.join("\n")}`;
12243
+ }
12244
+
12201
12245
  // src/commands/memory.ts
12202
12246
  var searchColumns = [
12203
12247
  { key: "title", header: "Title", width: 30 },
12204
12248
  { key: "layer", header: "Layer", width: 12 },
12205
12249
  { key: "freshness", header: "Freshness", width: 10 },
12250
+ { key: "source", header: "Source" },
12206
12251
  {
12207
12252
  key: "preview",
12208
12253
  header: "Preview",
@@ -12298,7 +12343,12 @@ memoryCommand.command("create").description("Create a new memory in the active w
12298
12343
  });
12299
12344
  memoryCommand.command("search <query>").description("Semantic search across memories").option("--json", "Output as JSON").option("-k, --limit <number>", "Max results", "10").option("--layer <layer>", "Filter by layer").action(async (query, opts, command) => {
12300
12345
  const g = globalOutputOpts(command);
12301
- const client2 = await buildClient();
12346
+ const auth = await resolveAuth();
12347
+ const client2 = new GadClient({
12348
+ token: auth.token,
12349
+ getToken: auth.getToken,
12350
+ apiUrl: auth.apiUrl
12351
+ });
12302
12352
  const args = {
12303
12353
  query,
12304
12354
  k: Number.parseInt(opts.limit, 10)
@@ -12312,6 +12362,7 @@ memoryCommand.command("search <query>").description("Semantic search across memo
12312
12362
  const rows = rawResults.map((item) => ({
12313
12363
  ...item,
12314
12364
  title: item.title ?? item.memoryTitle,
12365
+ source: sourceOf(item, auth.apiUrl).link ?? "",
12315
12366
  preview: extractPreview(item)
12316
12367
  }));
12317
12368
  const fmt = createFormatter({
@@ -18293,6 +18344,17 @@ function askOutcome(data) {
18293
18344
  const answer = extractAnswer(data);
18294
18345
  return answer.trim() === "" ? { kind: "empty" } : { kind: "ok", text: answer };
18295
18346
  }
18347
+ function askSources(data, apiUrl) {
18348
+ if (!data || typeof data !== "object") return "";
18349
+ const hits = data.hits;
18350
+ if (!Array.isArray(hits)) return "";
18351
+ return formatSources(
18352
+ uniqueSources(
18353
+ hits.filter((h) => typeof h === "object" && h !== null),
18354
+ apiUrl
18355
+ )
18356
+ );
18357
+ }
18296
18358
  function askCommand() {
18297
18359
  const cmd = new Command("ask").description("Ask the orchestrator a question").argument("<question>", "The question to ask").option("--json", "Output raw response as JSON").option("--quiet", "Suppress decorative output").option("--no-color", "Disable color output").action(async (question, options, command) => {
18298
18360
  const g = globalOutputOpts(command);
@@ -18329,6 +18391,10 @@ function askCommand() {
18329
18391
  const outcome = askOutcome(result);
18330
18392
  if (outcome.kind === "ok") {
18331
18393
  process.stdout.write(outcome.text + "\n");
18394
+ const sources = g.quiet ? "" : askSources(result, auth.apiUrl);
18395
+ if (sources) process.stdout.write(`
18396
+ ${sources}
18397
+ `);
18332
18398
  } else if (outcome.kind === "error") {
18333
18399
  fmt.warn(`Orchestrator error: ${outcome.message}`);
18334
18400
  process.exitCode = 1;
@@ -20107,7 +20173,7 @@ __export(external_exports, {
20107
20173
  hash: () => hash,
20108
20174
  hex: () => hex2,
20109
20175
  hostname: () => hostname4,
20110
- httpUrl: () => httpUrl,
20176
+ httpUrl: () => httpUrl2,
20111
20177
  iban: () => iban2,
20112
20178
  includes: () => _includes,
20113
20179
  input: () => input,
@@ -37046,7 +37112,7 @@ __export(schemas_exports2, {
37046
37112
  hash: () => hash,
37047
37113
  hex: () => hex2,
37048
37114
  hostname: () => hostname4,
37049
- httpUrl: () => httpUrl,
37115
+ httpUrl: () => httpUrl2,
37050
37116
  iban: () => iban2,
37051
37117
  instanceof: () => _instanceof,
37052
37118
  int: () => int,
@@ -37594,7 +37660,7 @@ var ZodURL = /* @__PURE__ */ $constructor("ZodURL", (inst, def) => {
37594
37660
  function url(params) {
37595
37661
  return _url(ZodURL, params);
37596
37662
  }
37597
- function httpUrl(params) {
37663
+ function httpUrl2(params) {
37598
37664
  return _url(ZodURL, {
37599
37665
  protocol: httpProtocol,
37600
37666
  hostname: domain,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@great-arrow/cli",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "GreatArrow.ai CLI tool",
5
5
  "type": "module",
6
6
  "bin": {