@codedology/code-forge 0.2.2 → 0.2.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 +7 -0
- package/package.json +1 -1
- package/skill/scripts/forge +1 -1
- package/src/cli/keys.mjs +2 -1
- package/src/install/wizard/run.mjs +7 -2
- package/src/keys/onepassword.mjs +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@ waits on a second real consumer (plan §10.4, Q17).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.2.3] — 2026-10-01
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- 1Password: code-forge prints a line before each call that may make 1Password ask for approval, and waits 60 s instead
|
|
14
|
+
of 20 s, so a Touch ID or password prompt no longer times out while you look for it.
|
|
15
|
+
|
|
9
16
|
## [0.2.2] — 2026-10-01
|
|
10
17
|
|
|
11
18
|
### Added
|
package/package.json
CHANGED
package/skill/scripts/forge
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# copied install with no package next to it); `test/skill/shim.test.mjs` asserts the pin
|
|
11
11
|
# equals package.json's version.
|
|
12
12
|
# The shim holds no logic of its own: every verb, flag and message is the CLI's.
|
|
13
|
-
PINNED_VERSION="0.2.
|
|
13
|
+
PINNED_VERSION="0.2.3"
|
|
14
14
|
set -eu
|
|
15
15
|
|
|
16
16
|
self="$0"
|
package/src/cli/keys.mjs
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { writeSafe } from '../util/redact.mjs';
|
|
19
|
-
import { describeOpItem, isOpRef, OP_MESSAGES, opItemIdFromInput, toOpRef } from '../keys/onepassword.mjs';
|
|
19
|
+
import { describeOpItem, isOpRef, OP_APPROVE_NOTE, OP_MESSAGES, opItemIdFromInput, toOpRef } from '../keys/onepassword.mjs';
|
|
20
20
|
import { assertKeyName, createDefaultKeyStore, parseRef, readOpAndCache, resolveKey } from '../keys/store.mjs';
|
|
21
21
|
|
|
22
22
|
const USAGE = 'usage: code-forge keys list | set <name> [--op <item-id|link|op://ref>] | test <name> [--ref <ref>] | remove <name>\n';
|
|
@@ -109,6 +109,7 @@ export async function runKeys(args, { store, stdout = process.stdout, stderr = p
|
|
|
109
109
|
err(`${name}: --op must be a 1Password item ID, item link or op://vault/item/field reference\n`);
|
|
110
110
|
return 2;
|
|
111
111
|
}
|
|
112
|
+
if (flagArg !== undefined && (itemId !== null || fullRef)) err(`${OP_APPROVE_NOTE}\n`);
|
|
112
113
|
// A 1Password item ID or link becomes a full op:// reference before any store call (B25).
|
|
113
114
|
if (flagArg !== undefined && itemId !== null) {
|
|
114
115
|
/** @type {Awaited<ReturnType<typeof toOpRef>>} */
|
|
@@ -26,7 +26,7 @@ import { parse as parseYAML } from 'yaml';
|
|
|
26
26
|
import { DEFAULT_CONFIG_FILENAME, loadConfigFile } from '../../config/load.mjs';
|
|
27
27
|
import { refreshFromCliCaches } from '../../config/refresh.mjs';
|
|
28
28
|
import { validateConfig } from '../../config/validate.mjs';
|
|
29
|
-
import { describeOpItem, isOpRef, OP_MESSAGES, toOpRef } from '../../keys/onepassword.mjs';
|
|
29
|
+
import { describeOpItem, isOpRef, OP_APPROVE_NOTE, OP_MESSAGES, opItemIdFromInput, toOpRef } from '../../keys/onepassword.mjs';
|
|
30
30
|
import { createDefaultKeyStore, resolveKey } from '../../keys/store.mjs';
|
|
31
31
|
import { exec } from '../../util/exec.mjs';
|
|
32
32
|
import { redact } from '../../util/redact.mjs';
|
|
@@ -261,7 +261,12 @@ export async function runInit(args, deps = {}) {
|
|
|
261
261
|
const missing = [];
|
|
262
262
|
let jevRef = null;
|
|
263
263
|
let jevSource = 'none';
|
|
264
|
-
const resolveOp = (/** @type {string} */ input) =>
|
|
264
|
+
const resolveOp = (/** @type {string} */ input) => {
|
|
265
|
+
// printed at once (stderr), not buffered: the approval prompt appears while op waits
|
|
266
|
+
// only when op will really be called: an item ID or a 1Password link (an op:// ref is kept as is)
|
|
267
|
+
if (opItemIdFromInput(String(input ?? '')) !== null) stderr.write(`${OP_APPROVE_NOTE}\n`);
|
|
268
|
+
return toOpRef(input, deps.opExec ? { exec: deps.opExec } : {});
|
|
269
|
+
};
|
|
265
270
|
/** @param {import('./steps.mjs').JevAnswer} a */
|
|
266
271
|
const takeAnswer = (a) => {
|
|
267
272
|
jevRef = a.ref;
|
package/src/keys/onepassword.mjs
CHANGED
|
@@ -13,7 +13,11 @@
|
|
|
13
13
|
|
|
14
14
|
import { exec as realExec } from '../util/exec.mjs';
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Long enough for a person to see and approve the 1Password prompt (Touch ID or password).
|
|
17
|
+
export const OP_TIMEOUT_MS = 60_000;
|
|
18
|
+
|
|
19
|
+
/** Shown just before a call that may make 1Password ask for approval. */
|
|
20
|
+
export const OP_APPROVE_NOTE = '1Password may ask you to approve access: check the 1Password window (Touch ID or password).';
|
|
17
21
|
|
|
18
22
|
/** The 1Password failure kinds; agent JSON carries the kind. */
|
|
19
23
|
export const OP_ERROR_KINDS = Object.freeze(['op_missing', 'op_locked', 'op_timeout', 'op_not_found', 'op_bad_output', 'op_no_field', 'op_bad_input', 'op_failed']);
|