@intercom/cli 0.8.2 → 0.8.3

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/CHANGELOG.md CHANGED
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  View it from the CLI with `intercom changelog`.
9
9
 
10
+ ## [0.8.3] - 2026-06-18
11
+
12
+ ### Fixed
13
+
14
+ - `fin workflows upload` now works with workflow YAML that doesn't declare a top-level `type:`. The upload endpoint is shared with procedures and routes by that field, so a workflow file without `type: workflow` was being validated as a procedure (`object at root is missing required properties: name, trigger_description, procedure`). The CLI now sets `type: workflow` for you when it's absent.
15
+ - `fin workflows enable` and `fin workflows disable` no longer fail with `Resource not found`. They re-upload the workflow after changing its state, and the re-uploaded YAML was missing `type: workflow`, so the server looked for a procedure with that id and 404'd. The state-change upload now carries `type: workflow`.
16
+ - `fin workflows get <id>` now prints the workflow as YAML (the format `upload` expects) instead of a lossy JSON summary, and accepts an optional output file: `intercom fin workflows get 42 workflow.yaml`. `--json` still returns parsed JSON.
17
+
10
18
  ## [0.8.2] - 2026-06-17
11
19
 
12
20
  ### Fixed
package/dist/index.js CHANGED
@@ -2814,6 +2814,24 @@ import { basename as basename2 } from "path";
2814
2814
  import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
2815
2815
  var STATE_LIVE = "live";
2816
2816
  var STATE_PAUSED = "paused";
2817
+ var WORKFLOW_TYPE = "workflow";
2818
+ function ensureWorkflowType(raw) {
2819
+ let parsed;
2820
+ try {
2821
+ parsed = parseYaml(raw);
2822
+ } catch {
2823
+ return raw;
2824
+ }
2825
+ if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) {
2826
+ return raw;
2827
+ }
2828
+ const obj = parsed;
2829
+ if (obj.type != null && obj.type !== "") {
2830
+ return raw;
2831
+ }
2832
+ obj.type = WORKFLOW_TYPE;
2833
+ return stringifyYaml(obj);
2834
+ }
2817
2835
  function registerWorkflowsCommand(fin) {
2818
2836
  const workflows = fin.command("workflows").description("Manage Fin SDK workflows");
2819
2837
  workflows.command("list").description("List Fin SDK workflows").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function() {
@@ -2834,22 +2852,31 @@ function registerWorkflowsCommand(fin) {
2834
2852
  return table({ columns: ["ID", "TITLE", "STATE", "TRIGGER"], rows });
2835
2853
  }, items);
2836
2854
  });
2837
- workflows.command("get <id>").description("Get a workflow by ID").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function(id) {
2855
+ workflows.command("get <id> [output]").description("Get a workflow by ID as YAML (writes to [output] file, or stdout)").option("--json", "Output as parsed JSON instead of YAML").option("--jq <expr>", "Filter parsed-JSON output with a jq expression").option("--verbose", "Show HTTP request/response details").addHelpText(
2856
+ "after",
2857
+ `
2858
+ Examples:
2859
+ $ intercom fin workflows get 42 workflow.yaml # write YAML to a file
2860
+ $ intercom fin workflows get 42 > workflow.yaml # or redirect stdout
2861
+ $ intercom fin workflows get 42 --json | jq .state
2862
+
2863
+ The YAML it prints is ready to edit and re-upload with
2864
+ \`intercom fin workflows upload\`.`
2865
+ ).action(async function(id, output) {
2838
2866
  const opts = this.optsWithGlobals();
2839
2867
  const client = await resolveClient(opts);
2840
2868
  const text = await client.getText(`/fin-sdk/workflows/${id}`);
2841
- const parsed = parseYaml(text);
2842
- render(
2843
- parsed,
2844
- opts,
2845
- () => detail({
2846
- "ID": String(parsed.id ?? ""),
2847
- "Title": String(parsed.title ?? ""),
2848
- "State": String(parsed.state ?? ""),
2849
- "Version": parsed.version != null ? String(parsed.version) : void 0,
2850
- "Trigger": parsed.trigger_type != null ? String(parsed.trigger_type) : void 0
2851
- })
2852
- );
2869
+ if (opts.json || opts.jq || opts.agent) {
2870
+ const parsed = parseYaml(text);
2871
+ render(parsed, opts, () => formatJson(parsed));
2872
+ return;
2873
+ }
2874
+ if (output) {
2875
+ await atomicWriteFile(output, text, 420);
2876
+ console.error(`Wrote workflow ${id} to ${output}`);
2877
+ } else {
2878
+ console.log(text.replace(/\n+$/, ""));
2879
+ }
2853
2880
  });
2854
2881
  workflows.command("upload <file>").description('Upload a workflow YAML file (creates if id is "new", updates if numeric)').option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").addHelpText(
2855
2882
  "after",
@@ -2865,9 +2892,10 @@ The YAML file's id field determines whether this creates or updates:
2865
2892
  ).action(async function(filePath) {
2866
2893
  const opts = this.optsWithGlobals();
2867
2894
  const client = await resolveClient(opts);
2868
- const fileContent = await readFile3(filePath);
2895
+ const fileContent = await readFile3(filePath, "utf8");
2896
+ const yamlBody = ensureWorkflowType(fileContent);
2869
2897
  const formData = new FormData();
2870
- const blob = new Blob([fileContent], { type: "application/x-yaml" });
2898
+ const blob = new Blob([yamlBody], { type: "application/x-yaml" });
2871
2899
  formData.append("file_data", blob, basename2(filePath));
2872
2900
  const result = await client.postFormData("/fin-sdk/upload", formData);
2873
2901
  render(
@@ -2901,6 +2929,7 @@ overwritten (the server does not expose a concurrency token).`
2901
2929
  } catch (err) {
2902
2930
  throw new Error(`server returned unparseable YAML for workflow ${id}: ${err.message}`);
2903
2931
  }
2932
+ parsed.type = WORKFLOW_TYPE;
2904
2933
  parsed.state = STATE_LIVE;
2905
2934
  const yamlBody = stringifyYaml(parsed);
2906
2935
  const formData = new FormData();
@@ -2937,6 +2966,7 @@ overwritten (the server does not expose a concurrency token).`
2937
2966
  } catch (err) {
2938
2967
  throw new Error(`server returned unparseable YAML for workflow ${id}: ${err.message}`);
2939
2968
  }
2969
+ parsed.type = WORKFLOW_TYPE;
2940
2970
  parsed.state = STATE_PAUSED;
2941
2971
  const yamlBody = stringifyYaml(parsed);
2942
2972
  const formData = new FormData();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intercom/cli",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "CLI tool for managing Intercom workspaces",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.23.0",