@meterapp/glossa 0.5.0 → 0.6.0

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
@@ -39,3 +39,12 @@ open the printed URL on any device (`--no-browser` skips opening one). To save
39
39
  an existing key instead, run `login --key gls_…`.
40
40
 
41
41
  In CI set `GLOSSA_API_KEY` (a workspace key, `gls_…`).
42
+
43
+ ### Cancel a background job
44
+
45
+ `glossa cancel <job-id>` cancels queued or running work. `glossa cancel_job --job <job-id>`
46
+ is the equivalent registry op. Completed translations remain in place, and repeated
47
+ cancellation is safe. An in-flight model request may finish; translation workers
48
+ check cancellation before storing its results or beginning the next batch.
49
+ Use `glossa get_job --job <job-id>` to inspect progress and final status, or
50
+ `glossa list_jobs --status cancelled` to list cancelled jobs.
package/bin/glossa.mjs CHANGED
@@ -9,7 +9,7 @@ import { dirname, join, relative, resolve } from "node:path";
9
9
  import { createInterface } from "node:readline";
10
10
  import { brotliCompressSync, brotliDecompressSync, constants as zlib } from "node:zlib";
11
11
 
12
- const VERSION = "0.5.0";
12
+ const VERSION = "0.6.0";
13
13
  const DEFAULT_HOST = "https://getglossa.dev";
14
14
  const CONFIG_PATH = join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "glossa", "config.json");
15
15
  /** The last failed call, so `glossa feedback report --last` can attach it. */
@@ -495,6 +495,14 @@ async function fill(positional, flags) {
495
495
  if (totals.rejected.length) process.exitCode = 1;
496
496
  }
497
497
 
498
+ export function cancelJobInput(positional, flags) {
499
+ const job = positional[0] ?? flags.job;
500
+ if (positional.length > 1 || typeof job !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(job)) {
501
+ throw new Error("Usage: glossa cancel <job-id> (or --job <job-id>)");
502
+ }
503
+ return { job };
504
+ }
505
+
498
506
  async function tasks(flags) {
499
507
  const { tasks: list, total } = await call("list_tasks", coerceFlags(flags, { properties: { limit: { type: "integer" }, kind: { type: "string" }, status: { type: "string" } } }));
500
508
  if (flags.json || !isTTY) return print({ total, tasks: list }, flags);
@@ -717,6 +725,7 @@ ${bold("Usage")}
717
725
  their keys and file paths, for an agent
718
726
  glossa fill <file.json|-> write translations: [{"unit","locale","text"}]
719
727
  [--status reviewed|needs_review] [--overwrite missing|machine|all]
728
+ glossa cancel <job-id> cancel queued or running work; keeps completed translations
720
729
  glossa tasks [--kind k] [--limit n] the review queue
721
730
  glossa mcp stdio MCP bridge to the hosted server
722
731
  glossa pricing [--json] plans, prices and limits (no key needed)
@@ -767,6 +776,8 @@ async function main() {
767
776
  return missing(flags);
768
777
  case "fill":
769
778
  return fill(positional, flags);
779
+ case "cancel":
780
+ return print(await call("cancel_job", cancelJobInput(positional, flags)), flags);
770
781
  case "tasks":
771
782
  return tasks(flags);
772
783
  case "mcp":
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { coerceFlags, deviceLogin, feedbackCall, fileBody, fileText, parseArgs, readJsonArg, fillBatches, pricingLines, reportInput, reviewInput, subscribeInput } from "./glossa.mjs";
2
+ import { cancelJobInput, coerceFlags, deviceLogin, feedbackCall, fileBody, fileText, parseArgs, readJsonArg, fillBatches, pricingLines, reportInput, reviewInput, subscribeInput } from "./glossa.mjs";
3
3
  import { pricingDocument } from "../../../lib/billing/pricing";
4
4
 
5
5
  describe("cli args", () => {
@@ -147,3 +147,15 @@ describe("feedback", () => {
147
147
  expect(() => reviewInput({})).toThrow(/rate 1 to 5/);
148
148
  });
149
149
  });
150
+
151
+
152
+ describe("cancel", () => {
153
+ const job = "bcae2e7c-cbc6-466b-8d97-c21ac165d099";
154
+ it("accepts one job id as a positional or flag", () => {
155
+ expect(cancelJobInput([job], {})).toEqual({ job });
156
+ expect(cancelJobInput([], { job })).toEqual({ job });
157
+ });
158
+ it("rejects missing, malformed or extra ids", () => {
159
+ for (const ids of [[], ["invalid"], [job, job]]) expect(() => cancelJobInput(ids, {})).toThrow(/Usage/);
160
+ });
161
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meterapp/glossa",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Glossa CLI: push and pull translation files, run the AI review queue, and every other Glossa op from your terminal or CI. Includes a stdio MCP bridge.",
5
5
  "type": "module",
6
6
  "bin": { "glossa": "bin/glossa.mjs" },