sealcode 1.1.0 → 1.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sealcode",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Lock your source code in your own git repo. Stop AI agents, scrapers, and curious eyes from reading what's yours.",
5
5
  "keywords": [
6
6
  "encryption",
package/src/cli-grants.js CHANGED
@@ -74,17 +74,38 @@ function getActiveConfig(projectRoot) {
74
74
  * a real cryptographic bug; we don't want to silently downgrade in that
75
75
  * case).
76
76
  */
77
- async function maybeWrapKeyForRecipient({ projectRoot, recipientEmail, verbose = false }) {
77
+ async function maybeWrapKeyForRecipient({
78
+ projectRoot,
79
+ recipientEmail,
80
+ verbose = false,
81
+ resolveKey = null,
82
+ }) {
78
83
  if (!recipientEmail) return null;
79
84
 
80
- // Need the master key K to wrap. If there's no live session on this
81
- // machine, we can't wrap owner has to `sealcode unlock` first.
85
+ // Need the master key K to wrap. Prefer a cached session; if none, ask
86
+ // the caller (cli.js) to prompt for the passphrase. We deliberately do
87
+ // NOT silently downgrade to "passphrase fallback" here — the whole point
88
+ // of `--email` is to spare the recipient the passphrase exchange.
82
89
  const config = getActiveConfig(projectRoot);
83
90
  if (!isInitialized(projectRoot, config.lockedDir)) return null;
84
- const K = loadSession(projectRoot);
91
+ let K = loadSession(projectRoot);
92
+ if (!K && typeof resolveKey === 'function') {
93
+ if (verbose) {
94
+ ui.step('No cached master key — prompting for passphrase so we can wrap for the recipient.');
95
+ }
96
+ try {
97
+ K = await resolveKey(projectRoot, config);
98
+ } catch (err) {
99
+ if (verbose) {
100
+ ui.warn(`Could not derive master key (${err.message || err}). Will mint without wrapping.`);
101
+ }
102
+ return null;
103
+ }
104
+ }
85
105
  if (!K) {
86
106
  if (verbose) {
87
- ui.hint('(no cached sessionskipping team-key wrap; recipient will need the passphrase)');
107
+ ui.warn('No cached master key minting code WITHOUT wrapped key. Recipient will need the passphrase.');
108
+ ui.hint('Run `sealcode unlock` first, or supply a passphrase prompt, to enable passphrase-free sharing.');
88
109
  }
89
110
  return null;
90
111
  }
@@ -100,13 +121,14 @@ async function maybeWrapKeyForRecipient({ projectRoot, recipientEmail, verbose =
100
121
  } catch (err) {
101
122
  if (err instanceof ApiError) {
102
123
  if (err.status === 404) {
103
- // Either the user doesn't exist or hasn't published a pubkey
104
- // yet. We still mint the code; the recipient just falls back to
105
- // the legacy flow when they redeem.
106
124
  if (verbose) {
125
+ ui.warn(
126
+ `Recipient ${recipientEmail} hasn't signed in to sealcode.dev yet, so no pubkey is on file.`,
127
+ );
107
128
  ui.hint(
108
- `(recipient hasn't published a pubkey yet falling back to passphrase-share flow)`,
129
+ 'Ask them to visit https://sealcode.dev/login, then re-run `sealcode share --email`.',
109
130
  );
131
+ ui.hint('Continuing with passphrase-fallback for this code…');
110
132
  }
111
133
  return null;
112
134
  }
@@ -146,6 +168,7 @@ async function runShare({
146
168
  singleDeviceEnforce = false,
147
169
  ndaText = null,
148
170
  json = false,
171
+ resolveKey = null,
149
172
  }) {
150
173
  const link = requireLink(projectRoot);
151
174
 
@@ -159,6 +182,7 @@ async function runShare({
159
182
  projectRoot,
160
183
  recipientEmail: email,
161
184
  verbose: !json,
185
+ resolveKey,
162
186
  });
163
187
  } catch (err) {
164
188
  // Network errors during pubkey lookup shouldn't be silent — degrade
package/src/cli.js CHANGED
@@ -714,6 +714,7 @@ function build() {
714
714
  singleDeviceEnforce: !!opts.singleDevice,
715
715
  ndaText: opts.nda || null,
716
716
  json: !!opts.json,
717
+ resolveKey,
717
718
  });
718
719
  } catch (err) {
719
720
  process.exitCode = reportError(err);