bsmnt 0.6.3 → 0.6.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bsmnt",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "packageManager": "bun@1.3.14",
5
5
  "description": "CLI to scaffold basement projects and add integrations",
6
6
  "type": "module",
@@ -4,7 +4,10 @@
4
4
  // bun run env:save
5
5
 
6
6
  import { spawnSync } from "node:child_process";
7
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { randomUUID } from "node:crypto";
8
+ import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
9
+ import { tmpdir } from "node:os";
10
+ import { join } from "node:path";
8
11
  import { createInterface } from "node:readline/promises";
9
12
 
10
13
  const VAULT = "Development";
@@ -87,22 +90,34 @@ if (existing.status === 0) {
87
90
  );
88
91
  }
89
92
 
90
- // 5. Create the item. Category/title/tags must be flags (op ignores them in a
91
- // piped template); the key goes in the stdin template (`-` first) so it stays
92
- // off argv. The field needs an `id` or op drops it.
93
- const args = ["item", "create", "-", "--category", "Secure Note", "--title", title];
94
- if (tag) args.push("--tags", tag);
95
- args.push("--vault", VAULT, "--format", "json");
93
+ // 5. Create the item from a temp template file (0600, unlinked after). Not stdin
94
+ // bun's spawnSync drops `input`, leaving an empty note; not assignments
95
+ // those leak the key into argv. The field needs an `id` or op drops it.
96
96
  const template = {
97
+ title,
98
+ category: "SECURE_NOTE",
99
+ ...(tag ? { tags: [tag] } : {}),
97
100
  fields: [
98
101
  { id: "private-key", type: "CONCEALED", label: "private-key", value: privateKey },
99
102
  ],
100
103
  };
101
- const created = spawnSync("op", args, {
102
- input: JSON.stringify(template),
103
- encoding: "utf-8",
104
- stdio: ["pipe", "pipe", "inherit"],
105
- });
104
+ const templatePath = join(tmpdir(), `bsmnt-op-${randomUUID()}.json`);
105
+ let created;
106
+ try {
107
+ // Inside the try so a partial write is still cleaned up by `finally`.
108
+ writeFileSync(templatePath, JSON.stringify(template), { mode: 0o600 });
109
+ created = spawnSync(
110
+ "op",
111
+ ["item", "create", "--template", templatePath, "--vault", VAULT, "--format", "json"],
112
+ { encoding: "utf-8", stdio: ["ignore", "pipe", "inherit"] },
113
+ );
114
+ } finally {
115
+ try {
116
+ unlinkSync(templatePath);
117
+ } catch {
118
+ // best-effort cleanup
119
+ }
120
+ }
106
121
  if (created.status !== 0) fail("\nFailed to create the 1Password item.");
107
122
 
108
123
  // 6. Reference the item by id (stable; survives renames), falling back to title.