Release: npm@6.5.0 - #105

Merged
zkat merged 47 commits into
latestfrom
release-next
Dec 10, 2018
Merged

Release: npm@6.5.0#105
zkat merged 47 commits into
latestfrom
release-next

Conversation

@zkat

@zkatzkat commented Nov 28, 2018

Copy link
Copy Markdown
Contributor

bakkotand others added 30 commits August 29, 2018 11:40
Oops: 7984206 did the
wrong thing with the git params, and it breaks anyone
trying to sign their git commits with npm version.
Fixes: https://npm.community/t/1661
Credit: @zkat
Fix browser opening under Windows Subsystem for Linux (WSL).
Credit: @thijsputman
With some tests I note npm use default branch of repository instead of `master`.
PR-URL: #64
Credit: @zckrs
Reviewed-By: @zkat
I found this page useful for setting up npm command completion. Thank you npm documentation team.
This suggested changed is based on my system which runs Ubuntu where
the completion directory path for bash is found in /etc/bash_completion.d and not /usr/local/etc/bash_completion.d
I dug around docs for this in The Bash Manual https://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion and on some an old (sadly retired) Debian Admin Site
https://debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
which seemed supportive of the dir being in /etc but I do not have access to an OS X machine where I guess bash_completion.d could be in /usr/local/etc so I left it in.
PR-URL: #72
Credit: @RobertKielty
Reviewed-By: @zkat
See discussion here: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
TL;DR:
> To be clear, you can specify an existing tag and it’ll change it. If you have 2FA enabled, you do need to specify `--otp` and if you don’t, you should get a `401` as above.
Ref: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
PR-URL: #74
Credit: @scotttrinh
Reviewed-By: @iarna
Reviewed-By: @zkat
* edit: fix handling of scoped packages
* edit: fix usage info
* docs: fix docs for the npm-edit command
PR-URL: #75
Credit: @larsgw
Reviewed-By: @iarna
PR-URL: #78
Credit: @hugovk
Reviewed-By: @zkat
This fixes https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3 and the other dozen or so issues that that link references, and possibly many more involving poor error messages from errors thrown by the upload function. @zkat you mentioned you could take a look at any fixes / answer any questions, if you could look this over and let me know if this is a good / valid approach that would be fantastic, thanks! (it wasn't a race condition, luckily :P).
it may also be helpful to add something like ```
if (!auth.token || !(auth.username && auth.password)) {
log.warn('publish', 'not logged in')
}
```
just before we even open the first file descriptor to make sure that even if the error message is completely wrong something in the log will give users a clue what may be going on. I took the method of looking for login creds from the logout method, I'm not sure that's valid or if alternatives to npm exist that don't require credentials but users could still publish to.
Triage of the issue:
1. The upload function throws an error
2. As that error bubbles through [cacache](https://www.npmjs.com/package/cacache#with-tmp) it tries to delete the tmpdir as it should
3. It can't delete the temp dir as the upload function's readFileStream to the tar it was trying to upload is still open.
4. [cacache](https://www.npmjs.com/package/cacache#with-tmp) throws an error about it's inability to remove the dir, which suppresses the upload function's error.
Fixes: https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3
PR-URL: #80
Credit: @macdja38
Reviewed-By: @zkat
* feat(cli, outdated): Adds 'Homepage' to outdated --long output.
- `package.json`'s `homepage` property is displayed when using the `--long` option for `npm outdated`
* test: npm outdated --long
- Adds `homepage` to `--parseable` output.
- Updates `npm outdated --long` test to include `homepage` in expected output.
- Adds `homepage` to `npm-outdated` documentation.
* fix: javascript standard style updates
PR-URL: #81
Credit: @jbottigliero
Reviewed-By: @zkat
… publish (#83)
Not sure when `--dry-run` was introduced, I assume it was introduced in npm 6 (correct me if I'm wrong). Anyway, hopefully this will prevent future developers from making the mistake of using it in npm 5 (like I did).
PR-URL: #83
Credit: @kjin
Reviewed-By: @zkat
@booc0mtaco

Copy link
Copy Markdown

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

@aeschright

Copy link
Copy Markdown
Contributor

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

Fixed in #96 for this release.

iarnaand others added 9 commits December 6, 2018 16:36
setuid() can not accept a 'nobody' parameter on IBM i.
The default user (QSECOFR) on IBM i has user id 0.
PR-URL: #65
Credit: @dmabupt
Reviewed-By: @zkat
Pass git binary path config to pacote.
Ref: zkat/pacote#164
Fixes: https://npm.community/t/3278
PR-URL: #98
Credit: @larsgw
Reviewed-By: @zkat
I keep typing `npm dist-tags` expecting it to print out a list of
dist-tags and instead it yells at me and that feels very un-npm-y.
PR-URL: #106
Credit: @isaacs
Reviewed-By: @zkat
@zkat
zkat merged commit 90e55a1 into latestDec 10, 2018
Jah-yee pushed a commit to Jah-yee/cli that referenced this pull request Apr 16, 2026
* feat(gmail): add +reply, +reply-all, and +forward helper commands
Add first-class reply and forward support to the Gmail helpers,
addressing the gap described in npm#88. These commands handle the
complex RFC 2822 threading mechanics (In-Reply-To, References,
threadId) that agents and CLI users struggle with today.
New commands:
- +reply: reply to a message with automatic threading
- +reply-all: reply to all recipients with --remove/--cc support
- +forward: forward a message with quoted original content
* fix(gmail): encode message_id in URL path and fix auth signature
- Use crate::validate::encode_path_segment() on message_id in
fetch_message_metadata URL construction per AGENTS.md rules
- Update auth::get_token calls to pass None for the new account
parameter added on main
* refactor(gmail): extract send_raw_email and deduplicate handlers
- Add send_raw_email() to mod.rs: shared encode→json→auth→execute
pattern for sending raw RFC 2822 messages via users.messages.send
- Simplify handle_reply: delegate send logic to send_raw_email
- Simplify handle_forward: delegate send logic to send_raw_email
Addresses code duplication feedback from PR review.
* fix(gmail): register --dry-run flag on reply/forward commands
The handlers read matches.get_flag("dry-run") but the flag was missing
from the clap command definitions, so it always returned false. Now
dry-run works for +reply, +reply-all, and +forward.
* chore: add changeset for gmail reply/forward feature
* style: apply cargo fmt formatting
* fix(gmail): register --dry-run flag on +send command
Same class of bug fixed for +reply/+reply-all/+forward — the handler
reads matches.get_flag("dry-run") but the arg was not registered.
* fix(gmail): honor Reply-To header and use exact address matching
- Prefer Reply-To over From when selecting reply recipients, fixing
incorrect routing for mailing lists and support systems
- Use exact email address comparison instead of substring matching
for --remove filtering and sender deduplication, preventing
unintended recipient removal (e.g. ann@ no longer drops joann@)
* test(gmail): add comprehensive coverage for reply address handling
- extract_email: malformed input (no closing bracket), empty string,
whitespace-only
- build_reply_all_recipients: display-name sender exclusion,
--remove with display name, extra --cc, CC becomes None when all
filtered, case-insensitive sender exclusion
* Improves reply-all recipient deduplication
Corrects how `build_reply_all_recipients` handles multi-address `Reply-To` headers.
Previously, only the first address from `Reply-To` was used for deduplication, leading to potential redundancy by including those addresses in the `Cc` field.
The updated logic now parses all addresses in `Reply-To`, ensuring they are fully moved to the `To` field and properly excluded from `Cc`.
* style(gmail): add missing Apache 2.0 copyright headers
reply.rs and forward.rs were missing the copyright header that all
other source files in the repo include.
* fix(gmail): use try_get_one for optional --remove arg in +reply
parse_reply_args used get_one("remove") which panics when called
from +reply (which does not register --remove). Switch to
try_get_one to safely return None for unregistered args.
* feat(gmail): support --dry-run without auth for reply/forward commands
Skip auth and message fetch when --dry-run is set by using placeholder
OriginalMessage data. This lets users preview the request structure
without needing credentials.
* fix(gmail): use RFC-aware mailbox list parsing for recipient splitting
Replace naive comma-split with split_mailbox_list that respects
quoted strings, so display names containing commas like
"Doe, John" <john@example.com> are handled correctly in reply-all
recipient parsing, deduplication, and --remove filtering.
* fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting
for backslash-escaped quotes (`\"`), causing display names like
`"Doe \"JD, Sr\""` to split incorrectly at interior commas.
Track `prev_backslash` so `\"` inside quoted strings is treated as a
literal quote character rather than a delimiter toggle. Double
backslashes (`\\`) are handled correctly as well.
* fix(gmail): address PR review feedback for reply/forward helpers
- Use reqwest .query() for metadata params per AGENTS.md convention
- Add MIME-Version and Content-Type headers to raw messages
- Add --from flag to +reply, +reply-all, +forward for send-as/alias
- Narrow ReplyConfig/ForwardConfig visibility to pub(super)
- Refactor create_reply_raw_message args into ReplyEnvelope struct
* fix(gmail): address review feedback for reply/forward helpers
- Exclude authenticated user's own email from reply-all CC by
fetching user profile via Gmail API
- Use format=full to extract full plain-text body instead of
truncated snippet for quoting and forwarding
- Deduplicate CC addresses using a HashSet
- Reuse auth token from message fetch in send_raw_email to
eliminate double auth round-trip
- Propagate auth errors in send_raw_email instead of silently
falling back to unauthenticated requests
- Use consistent CRLF line endings in quoted and forwarded
message bodies per RFC 2822
* fix(gmail): Gmail reply and forward helpers
* fix(gmail): refactor shared reply-forward helpers
* Preserve repeated Gmail address headers
* chore: regenerate skills [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jun 30, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 2, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 11, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Aug 6, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

18 participants

@zkat@booc0mtaco@aeschright@slavafomin@maartenvanbenthem@bakkot@maartenba@iarna@kemitchell@RobertKielty@scotttrinh@larsgw@hugovk@alopezsanchez@macdja38@seishun@kjin@kitayoshi
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Release: npm@6.5.0 - #105

Merged
zkat merged 47 commits into
latestfrom
release-next
Dec 10, 2018
Merged

Release: npm@6.5.0#105
zkat merged 47 commits into
latestfrom
release-next

Conversation

@zkat

@zkatzkat commented Nov 28, 2018

Copy link
Copy Markdown
Contributor

bakkotand others added 30 commits August 29, 2018 11:40
Oops: 7984206 did the
wrong thing with the git params, and it breaks anyone
trying to sign their git commits with npm version.
Fixes: https://npm.community/t/1661
Credit: @zkat
Fix browser opening under Windows Subsystem for Linux (WSL).
Credit: @thijsputman
With some tests I note npm use default branch of repository instead of `master`.
PR-URL: #64
Credit: @zckrs
Reviewed-By: @zkat
I found this page useful for setting up npm command completion. Thank you npm documentation team.
This suggested changed is based on my system which runs Ubuntu where
the completion directory path for bash is found in /etc/bash_completion.d and not /usr/local/etc/bash_completion.d
I dug around docs for this in The Bash Manual https://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion and on some an old (sadly retired) Debian Admin Site
https://debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
which seemed supportive of the dir being in /etc but I do not have access to an OS X machine where I guess bash_completion.d could be in /usr/local/etc so I left it in.
PR-URL: #72
Credit: @RobertKielty
Reviewed-By: @zkat
See discussion here: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
TL;DR:
> To be clear, you can specify an existing tag and it’ll change it. If you have 2FA enabled, you do need to specify `--otp` and if you don’t, you should get a `401` as above.
Ref: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
PR-URL: #74
Credit: @scotttrinh
Reviewed-By: @iarna
Reviewed-By: @zkat
* edit: fix handling of scoped packages
* edit: fix usage info
* docs: fix docs for the npm-edit command
PR-URL: #75
Credit: @larsgw
Reviewed-By: @iarna
PR-URL: #78
Credit: @hugovk
Reviewed-By: @zkat
This fixes https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3 and the other dozen or so issues that that link references, and possibly many more involving poor error messages from errors thrown by the upload function. @zkat you mentioned you could take a look at any fixes / answer any questions, if you could look this over and let me know if this is a good / valid approach that would be fantastic, thanks! (it wasn't a race condition, luckily :P).
it may also be helpful to add something like ```
if (!auth.token || !(auth.username && auth.password)) {
log.warn('publish', 'not logged in')
}
```
just before we even open the first file descriptor to make sure that even if the error message is completely wrong something in the log will give users a clue what may be going on. I took the method of looking for login creds from the logout method, I'm not sure that's valid or if alternatives to npm exist that don't require credentials but users could still publish to.
Triage of the issue:
1. The upload function throws an error
2. As that error bubbles through [cacache](https://www.npmjs.com/package/cacache#with-tmp) it tries to delete the tmpdir as it should
3. It can't delete the temp dir as the upload function's readFileStream to the tar it was trying to upload is still open.
4. [cacache](https://www.npmjs.com/package/cacache#with-tmp) throws an error about it's inability to remove the dir, which suppresses the upload function's error.
Fixes: https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3
PR-URL: #80
Credit: @macdja38
Reviewed-By: @zkat
* feat(cli, outdated): Adds 'Homepage' to outdated --long output.
- `package.json`'s `homepage` property is displayed when using the `--long` option for `npm outdated`
* test: npm outdated --long
- Adds `homepage` to `--parseable` output.
- Updates `npm outdated --long` test to include `homepage` in expected output.
- Adds `homepage` to `npm-outdated` documentation.
* fix: javascript standard style updates
PR-URL: #81
Credit: @jbottigliero
Reviewed-By: @zkat
… publish (#83)
Not sure when `--dry-run` was introduced, I assume it was introduced in npm 6 (correct me if I'm wrong). Anyway, hopefully this will prevent future developers from making the mistake of using it in npm 5 (like I did).
PR-URL: #83
Credit: @kjin
Reviewed-By: @zkat
@booc0mtaco

Copy link
Copy Markdown

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

@aeschright

Copy link
Copy Markdown
Contributor

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

Fixed in #96 for this release.

iarnaand others added 9 commits December 6, 2018 16:36
setuid() can not accept a 'nobody' parameter on IBM i.
The default user (QSECOFR) on IBM i has user id 0.
PR-URL: #65
Credit: @dmabupt
Reviewed-By: @zkat
Pass git binary path config to pacote.
Ref: zkat/pacote#164
Fixes: https://npm.community/t/3278
PR-URL: #98
Credit: @larsgw
Reviewed-By: @zkat
I keep typing `npm dist-tags` expecting it to print out a list of
dist-tags and instead it yells at me and that feels very un-npm-y.
PR-URL: #106
Credit: @isaacs
Reviewed-By: @zkat
@zkat
zkat merged commit 90e55a1 into latestDec 10, 2018
Jah-yee pushed a commit to Jah-yee/cli that referenced this pull request Apr 16, 2026
* feat(gmail): add +reply, +reply-all, and +forward helper commands
Add first-class reply and forward support to the Gmail helpers,
addressing the gap described in npm#88. These commands handle the
complex RFC 2822 threading mechanics (In-Reply-To, References,
threadId) that agents and CLI users struggle with today.
New commands:
- +reply: reply to a message with automatic threading
- +reply-all: reply to all recipients with --remove/--cc support
- +forward: forward a message with quoted original content
* fix(gmail): encode message_id in URL path and fix auth signature
- Use crate::validate::encode_path_segment() on message_id in
fetch_message_metadata URL construction per AGENTS.md rules
- Update auth::get_token calls to pass None for the new account
parameter added on main
* refactor(gmail): extract send_raw_email and deduplicate handlers
- Add send_raw_email() to mod.rs: shared encode→json→auth→execute
pattern for sending raw RFC 2822 messages via users.messages.send
- Simplify handle_reply: delegate send logic to send_raw_email
- Simplify handle_forward: delegate send logic to send_raw_email
Addresses code duplication feedback from PR review.
* fix(gmail): register --dry-run flag on reply/forward commands
The handlers read matches.get_flag("dry-run") but the flag was missing
from the clap command definitions, so it always returned false. Now
dry-run works for +reply, +reply-all, and +forward.
* chore: add changeset for gmail reply/forward feature
* style: apply cargo fmt formatting
* fix(gmail): register --dry-run flag on +send command
Same class of bug fixed for +reply/+reply-all/+forward — the handler
reads matches.get_flag("dry-run") but the arg was not registered.
* fix(gmail): honor Reply-To header and use exact address matching
- Prefer Reply-To over From when selecting reply recipients, fixing
incorrect routing for mailing lists and support systems
- Use exact email address comparison instead of substring matching
for --remove filtering and sender deduplication, preventing
unintended recipient removal (e.g. ann@ no longer drops joann@)
* test(gmail): add comprehensive coverage for reply address handling
- extract_email: malformed input (no closing bracket), empty string,
whitespace-only
- build_reply_all_recipients: display-name sender exclusion,
--remove with display name, extra --cc, CC becomes None when all
filtered, case-insensitive sender exclusion
* Improves reply-all recipient deduplication
Corrects how `build_reply_all_recipients` handles multi-address `Reply-To` headers.
Previously, only the first address from `Reply-To` was used for deduplication, leading to potential redundancy by including those addresses in the `Cc` field.
The updated logic now parses all addresses in `Reply-To`, ensuring they are fully moved to the `To` field and properly excluded from `Cc`.
* style(gmail): add missing Apache 2.0 copyright headers
reply.rs and forward.rs were missing the copyright header that all
other source files in the repo include.
* fix(gmail): use try_get_one for optional --remove arg in +reply
parse_reply_args used get_one("remove") which panics when called
from +reply (which does not register --remove). Switch to
try_get_one to safely return None for unregistered args.
* feat(gmail): support --dry-run without auth for reply/forward commands
Skip auth and message fetch when --dry-run is set by using placeholder
OriginalMessage data. This lets users preview the request structure
without needing credentials.
* fix(gmail): use RFC-aware mailbox list parsing for recipient splitting
Replace naive comma-split with split_mailbox_list that respects
quoted strings, so display names containing commas like
"Doe, John" <john@example.com> are handled correctly in reply-all
recipient parsing, deduplication, and --remove filtering.
* fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting
for backslash-escaped quotes (`\"`), causing display names like
`"Doe \"JD, Sr\""` to split incorrectly at interior commas.
Track `prev_backslash` so `\"` inside quoted strings is treated as a
literal quote character rather than a delimiter toggle. Double
backslashes (`\\`) are handled correctly as well.
* fix(gmail): address PR review feedback for reply/forward helpers
- Use reqwest .query() for metadata params per AGENTS.md convention
- Add MIME-Version and Content-Type headers to raw messages
- Add --from flag to +reply, +reply-all, +forward for send-as/alias
- Narrow ReplyConfig/ForwardConfig visibility to pub(super)
- Refactor create_reply_raw_message args into ReplyEnvelope struct
* fix(gmail): address review feedback for reply/forward helpers
- Exclude authenticated user's own email from reply-all CC by
fetching user profile via Gmail API
- Use format=full to extract full plain-text body instead of
truncated snippet for quoting and forwarding
- Deduplicate CC addresses using a HashSet
- Reuse auth token from message fetch in send_raw_email to
eliminate double auth round-trip
- Propagate auth errors in send_raw_email instead of silently
falling back to unauthenticated requests
- Use consistent CRLF line endings in quoted and forwarded
message bodies per RFC 2822
* fix(gmail): Gmail reply and forward helpers
* fix(gmail): refactor shared reply-forward helpers
* Preserve repeated Gmail address headers
* chore: regenerate skills [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jun 30, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 2, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 11, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Aug 6, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

18 participants

@zkat@booc0mtaco@aeschright@slavafomin@maartenvanbenthem@bakkot@maartenba@iarna@kemitchell@RobertKielty@scotttrinh@larsgw@hugovk@alopezsanchez@macdja38@seishun@kjin@kitayoshi
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Release: npm@6.5.0 - #105

Merged
zkat merged 47 commits into
latestfrom
release-next
Dec 10, 2018
Merged

Release: npm@6.5.0#105
zkat merged 47 commits into
latestfrom
release-next

Conversation

@zkat

@zkatzkat commented Nov 28, 2018

Copy link
Copy Markdown
Contributor

bakkotand others added 30 commits August 29, 2018 11:40
Oops: 7984206 did the
wrong thing with the git params, and it breaks anyone
trying to sign their git commits with npm version.
Fixes: https://npm.community/t/1661
Credit: @zkat
Fix browser opening under Windows Subsystem for Linux (WSL).
Credit: @thijsputman
With some tests I note npm use default branch of repository instead of `master`.
PR-URL: #64
Credit: @zckrs
Reviewed-By: @zkat
I found this page useful for setting up npm command completion. Thank you npm documentation team.
This suggested changed is based on my system which runs Ubuntu where
the completion directory path for bash is found in /etc/bash_completion.d and not /usr/local/etc/bash_completion.d
I dug around docs for this in The Bash Manual https://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion and on some an old (sadly retired) Debian Admin Site
https://debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
which seemed supportive of the dir being in /etc but I do not have access to an OS X machine where I guess bash_completion.d could be in /usr/local/etc so I left it in.
PR-URL: #72
Credit: @RobertKielty
Reviewed-By: @zkat
See discussion here: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
TL;DR:
> To be clear, you can specify an existing tag and it’ll change it. If you have 2FA enabled, you do need to specify `--otp` and if you don’t, you should get a `401` as above.
Ref: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
PR-URL: #74
Credit: @scotttrinh
Reviewed-By: @iarna
Reviewed-By: @zkat
* edit: fix handling of scoped packages
* edit: fix usage info
* docs: fix docs for the npm-edit command
PR-URL: #75
Credit: @larsgw
Reviewed-By: @iarna
PR-URL: #78
Credit: @hugovk
Reviewed-By: @zkat
This fixes https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3 and the other dozen or so issues that that link references, and possibly many more involving poor error messages from errors thrown by the upload function. @zkat you mentioned you could take a look at any fixes / answer any questions, if you could look this over and let me know if this is a good / valid approach that would be fantastic, thanks! (it wasn't a race condition, luckily :P).
it may also be helpful to add something like ```
if (!auth.token || !(auth.username && auth.password)) {
log.warn('publish', 'not logged in')
}
```
just before we even open the first file descriptor to make sure that even if the error message is completely wrong something in the log will give users a clue what may be going on. I took the method of looking for login creds from the logout method, I'm not sure that's valid or if alternatives to npm exist that don't require credentials but users could still publish to.
Triage of the issue:
1. The upload function throws an error
2. As that error bubbles through [cacache](https://www.npmjs.com/package/cacache#with-tmp) it tries to delete the tmpdir as it should
3. It can't delete the temp dir as the upload function's readFileStream to the tar it was trying to upload is still open.
4. [cacache](https://www.npmjs.com/package/cacache#with-tmp) throws an error about it's inability to remove the dir, which suppresses the upload function's error.
Fixes: https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3
PR-URL: #80
Credit: @macdja38
Reviewed-By: @zkat
* feat(cli, outdated): Adds 'Homepage' to outdated --long output.
- `package.json`'s `homepage` property is displayed when using the `--long` option for `npm outdated`
* test: npm outdated --long
- Adds `homepage` to `--parseable` output.
- Updates `npm outdated --long` test to include `homepage` in expected output.
- Adds `homepage` to `npm-outdated` documentation.
* fix: javascript standard style updates
PR-URL: #81
Credit: @jbottigliero
Reviewed-By: @zkat
… publish (#83)
Not sure when `--dry-run` was introduced, I assume it was introduced in npm 6 (correct me if I'm wrong). Anyway, hopefully this will prevent future developers from making the mistake of using it in npm 5 (like I did).
PR-URL: #83
Credit: @kjin
Reviewed-By: @zkat
@booc0mtaco

Copy link
Copy Markdown

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

@aeschright

Copy link
Copy Markdown
Contributor

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

Fixed in #96 for this release.

iarnaand others added 9 commits December 6, 2018 16:36
setuid() can not accept a 'nobody' parameter on IBM i.
The default user (QSECOFR) on IBM i has user id 0.
PR-URL: #65
Credit: @dmabupt
Reviewed-By: @zkat
Pass git binary path config to pacote.
Ref: zkat/pacote#164
Fixes: https://npm.community/t/3278
PR-URL: #98
Credit: @larsgw
Reviewed-By: @zkat
I keep typing `npm dist-tags` expecting it to print out a list of
dist-tags and instead it yells at me and that feels very un-npm-y.
PR-URL: #106
Credit: @isaacs
Reviewed-By: @zkat
@zkat
zkat merged commit 90e55a1 into latestDec 10, 2018
Jah-yee pushed a commit to Jah-yee/cli that referenced this pull request Apr 16, 2026
* feat(gmail): add +reply, +reply-all, and +forward helper commands
Add first-class reply and forward support to the Gmail helpers,
addressing the gap described in npm#88. These commands handle the
complex RFC 2822 threading mechanics (In-Reply-To, References,
threadId) that agents and CLI users struggle with today.
New commands:
- +reply: reply to a message with automatic threading
- +reply-all: reply to all recipients with --remove/--cc support
- +forward: forward a message with quoted original content
* fix(gmail): encode message_id in URL path and fix auth signature
- Use crate::validate::encode_path_segment() on message_id in
fetch_message_metadata URL construction per AGENTS.md rules
- Update auth::get_token calls to pass None for the new account
parameter added on main
* refactor(gmail): extract send_raw_email and deduplicate handlers
- Add send_raw_email() to mod.rs: shared encode→json→auth→execute
pattern for sending raw RFC 2822 messages via users.messages.send
- Simplify handle_reply: delegate send logic to send_raw_email
- Simplify handle_forward: delegate send logic to send_raw_email
Addresses code duplication feedback from PR review.
* fix(gmail): register --dry-run flag on reply/forward commands
The handlers read matches.get_flag("dry-run") but the flag was missing
from the clap command definitions, so it always returned false. Now
dry-run works for +reply, +reply-all, and +forward.
* chore: add changeset for gmail reply/forward feature
* style: apply cargo fmt formatting
* fix(gmail): register --dry-run flag on +send command
Same class of bug fixed for +reply/+reply-all/+forward — the handler
reads matches.get_flag("dry-run") but the arg was not registered.
* fix(gmail): honor Reply-To header and use exact address matching
- Prefer Reply-To over From when selecting reply recipients, fixing
incorrect routing for mailing lists and support systems
- Use exact email address comparison instead of substring matching
for --remove filtering and sender deduplication, preventing
unintended recipient removal (e.g. ann@ no longer drops joann@)
* test(gmail): add comprehensive coverage for reply address handling
- extract_email: malformed input (no closing bracket), empty string,
whitespace-only
- build_reply_all_recipients: display-name sender exclusion,
--remove with display name, extra --cc, CC becomes None when all
filtered, case-insensitive sender exclusion
* Improves reply-all recipient deduplication
Corrects how `build_reply_all_recipients` handles multi-address `Reply-To` headers.
Previously, only the first address from `Reply-To` was used for deduplication, leading to potential redundancy by including those addresses in the `Cc` field.
The updated logic now parses all addresses in `Reply-To`, ensuring they are fully moved to the `To` field and properly excluded from `Cc`.
* style(gmail): add missing Apache 2.0 copyright headers
reply.rs and forward.rs were missing the copyright header that all
other source files in the repo include.
* fix(gmail): use try_get_one for optional --remove arg in +reply
parse_reply_args used get_one("remove") which panics when called
from +reply (which does not register --remove). Switch to
try_get_one to safely return None for unregistered args.
* feat(gmail): support --dry-run without auth for reply/forward commands
Skip auth and message fetch when --dry-run is set by using placeholder
OriginalMessage data. This lets users preview the request structure
without needing credentials.
* fix(gmail): use RFC-aware mailbox list parsing for recipient splitting
Replace naive comma-split with split_mailbox_list that respects
quoted strings, so display names containing commas like
"Doe, John" <john@example.com> are handled correctly in reply-all
recipient parsing, deduplication, and --remove filtering.
* fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting
for backslash-escaped quotes (`\"`), causing display names like
`"Doe \"JD, Sr\""` to split incorrectly at interior commas.
Track `prev_backslash` so `\"` inside quoted strings is treated as a
literal quote character rather than a delimiter toggle. Double
backslashes (`\\`) are handled correctly as well.
* fix(gmail): address PR review feedback for reply/forward helpers
- Use reqwest .query() for metadata params per AGENTS.md convention
- Add MIME-Version and Content-Type headers to raw messages
- Add --from flag to +reply, +reply-all, +forward for send-as/alias
- Narrow ReplyConfig/ForwardConfig visibility to pub(super)
- Refactor create_reply_raw_message args into ReplyEnvelope struct
* fix(gmail): address review feedback for reply/forward helpers
- Exclude authenticated user's own email from reply-all CC by
fetching user profile via Gmail API
- Use format=full to extract full plain-text body instead of
truncated snippet for quoting and forwarding
- Deduplicate CC addresses using a HashSet
- Reuse auth token from message fetch in send_raw_email to
eliminate double auth round-trip
- Propagate auth errors in send_raw_email instead of silently
falling back to unauthenticated requests
- Use consistent CRLF line endings in quoted and forwarded
message bodies per RFC 2822
* fix(gmail): Gmail reply and forward helpers
* fix(gmail): refactor shared reply-forward helpers
* Preserve repeated Gmail address headers
* chore: regenerate skills [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jun 30, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 2, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 11, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Aug 6, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

18 participants

@zkat@booc0mtaco@aeschright@slavafomin@maartenvanbenthem@bakkot@maartenba@iarna@kemitchell@RobertKielty@scotttrinh@larsgw@hugovk@alopezsanchez@macdja38@seishun@kjin@kitayoshi
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Release: npm@6.5.0 - #105

Merged
zkat merged 47 commits into
latestfrom
release-next
Dec 10, 2018
Merged

Release: npm@6.5.0#105
zkat merged 47 commits into
latestfrom
release-next

Conversation

@zkat

@zkatzkat commented Nov 28, 2018

Copy link
Copy Markdown
Contributor

bakkotand others added 30 commits August 29, 2018 11:40
Oops: 7984206 did the
wrong thing with the git params, and it breaks anyone
trying to sign their git commits with npm version.
Fixes: https://npm.community/t/1661
Credit: @zkat
Fix browser opening under Windows Subsystem for Linux (WSL).
Credit: @thijsputman
With some tests I note npm use default branch of repository instead of `master`.
PR-URL: #64
Credit: @zckrs
Reviewed-By: @zkat
I found this page useful for setting up npm command completion. Thank you npm documentation team.
This suggested changed is based on my system which runs Ubuntu where
the completion directory path for bash is found in /etc/bash_completion.d and not /usr/local/etc/bash_completion.d
I dug around docs for this in The Bash Manual https://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion and on some an old (sadly retired) Debian Admin Site
https://debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
which seemed supportive of the dir being in /etc but I do not have access to an OS X machine where I guess bash_completion.d could be in /usr/local/etc so I left it in.
PR-URL: #72
Credit: @RobertKielty
Reviewed-By: @zkat
See discussion here: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
TL;DR:
> To be clear, you can specify an existing tag and it’ll change it. If you have 2FA enabled, you do need to specify `--otp` and if you don’t, you should get a `401` as above.
Ref: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
PR-URL: #74
Credit: @scotttrinh
Reviewed-By: @iarna
Reviewed-By: @zkat
* edit: fix handling of scoped packages
* edit: fix usage info
* docs: fix docs for the npm-edit command
PR-URL: #75
Credit: @larsgw
Reviewed-By: @iarna
PR-URL: #78
Credit: @hugovk
Reviewed-By: @zkat
This fixes https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3 and the other dozen or so issues that that link references, and possibly many more involving poor error messages from errors thrown by the upload function. @zkat you mentioned you could take a look at any fixes / answer any questions, if you could look this over and let me know if this is a good / valid approach that would be fantastic, thanks! (it wasn't a race condition, luckily :P).
it may also be helpful to add something like ```
if (!auth.token || !(auth.username && auth.password)) {
log.warn('publish', 'not logged in')
}
```
just before we even open the first file descriptor to make sure that even if the error message is completely wrong something in the log will give users a clue what may be going on. I took the method of looking for login creds from the logout method, I'm not sure that's valid or if alternatives to npm exist that don't require credentials but users could still publish to.
Triage of the issue:
1. The upload function throws an error
2. As that error bubbles through [cacache](https://www.npmjs.com/package/cacache#with-tmp) it tries to delete the tmpdir as it should
3. It can't delete the temp dir as the upload function's readFileStream to the tar it was trying to upload is still open.
4. [cacache](https://www.npmjs.com/package/cacache#with-tmp) throws an error about it's inability to remove the dir, which suppresses the upload function's error.
Fixes: https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3
PR-URL: #80
Credit: @macdja38
Reviewed-By: @zkat
* feat(cli, outdated): Adds 'Homepage' to outdated --long output.
- `package.json`'s `homepage` property is displayed when using the `--long` option for `npm outdated`
* test: npm outdated --long
- Adds `homepage` to `--parseable` output.
- Updates `npm outdated --long` test to include `homepage` in expected output.
- Adds `homepage` to `npm-outdated` documentation.
* fix: javascript standard style updates
PR-URL: #81
Credit: @jbottigliero
Reviewed-By: @zkat
… publish (#83)
Not sure when `--dry-run` was introduced, I assume it was introduced in npm 6 (correct me if I'm wrong). Anyway, hopefully this will prevent future developers from making the mistake of using it in npm 5 (like I did).
PR-URL: #83
Credit: @kjin
Reviewed-By: @zkat
@booc0mtaco

Copy link
Copy Markdown

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

@aeschright

Copy link
Copy Markdown
Contributor

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

Fixed in #96 for this release.

iarnaand others added 9 commits December 6, 2018 16:36
setuid() can not accept a 'nobody' parameter on IBM i.
The default user (QSECOFR) on IBM i has user id 0.
PR-URL: #65
Credit: @dmabupt
Reviewed-By: @zkat
Pass git binary path config to pacote.
Ref: zkat/pacote#164
Fixes: https://npm.community/t/3278
PR-URL: #98
Credit: @larsgw
Reviewed-By: @zkat
I keep typing `npm dist-tags` expecting it to print out a list of
dist-tags and instead it yells at me and that feels very un-npm-y.
PR-URL: #106
Credit: @isaacs
Reviewed-By: @zkat
@zkat
zkat merged commit 90e55a1 into latestDec 10, 2018
Jah-yee pushed a commit to Jah-yee/cli that referenced this pull request Apr 16, 2026
* feat(gmail): add +reply, +reply-all, and +forward helper commands
Add first-class reply and forward support to the Gmail helpers,
addressing the gap described in npm#88. These commands handle the
complex RFC 2822 threading mechanics (In-Reply-To, References,
threadId) that agents and CLI users struggle with today.
New commands:
- +reply: reply to a message with automatic threading
- +reply-all: reply to all recipients with --remove/--cc support
- +forward: forward a message with quoted original content
* fix(gmail): encode message_id in URL path and fix auth signature
- Use crate::validate::encode_path_segment() on message_id in
fetch_message_metadata URL construction per AGENTS.md rules
- Update auth::get_token calls to pass None for the new account
parameter added on main
* refactor(gmail): extract send_raw_email and deduplicate handlers
- Add send_raw_email() to mod.rs: shared encode→json→auth→execute
pattern for sending raw RFC 2822 messages via users.messages.send
- Simplify handle_reply: delegate send logic to send_raw_email
- Simplify handle_forward: delegate send logic to send_raw_email
Addresses code duplication feedback from PR review.
* fix(gmail): register --dry-run flag on reply/forward commands
The handlers read matches.get_flag("dry-run") but the flag was missing
from the clap command definitions, so it always returned false. Now
dry-run works for +reply, +reply-all, and +forward.
* chore: add changeset for gmail reply/forward feature
* style: apply cargo fmt formatting
* fix(gmail): register --dry-run flag on +send command
Same class of bug fixed for +reply/+reply-all/+forward — the handler
reads matches.get_flag("dry-run") but the arg was not registered.
* fix(gmail): honor Reply-To header and use exact address matching
- Prefer Reply-To over From when selecting reply recipients, fixing
incorrect routing for mailing lists and support systems
- Use exact email address comparison instead of substring matching
for --remove filtering and sender deduplication, preventing
unintended recipient removal (e.g. ann@ no longer drops joann@)
* test(gmail): add comprehensive coverage for reply address handling
- extract_email: malformed input (no closing bracket), empty string,
whitespace-only
- build_reply_all_recipients: display-name sender exclusion,
--remove with display name, extra --cc, CC becomes None when all
filtered, case-insensitive sender exclusion
* Improves reply-all recipient deduplication
Corrects how `build_reply_all_recipients` handles multi-address `Reply-To` headers.
Previously, only the first address from `Reply-To` was used for deduplication, leading to potential redundancy by including those addresses in the `Cc` field.
The updated logic now parses all addresses in `Reply-To`, ensuring they are fully moved to the `To` field and properly excluded from `Cc`.
* style(gmail): add missing Apache 2.0 copyright headers
reply.rs and forward.rs were missing the copyright header that all
other source files in the repo include.
* fix(gmail): use try_get_one for optional --remove arg in +reply
parse_reply_args used get_one("remove") which panics when called
from +reply (which does not register --remove). Switch to
try_get_one to safely return None for unregistered args.
* feat(gmail): support --dry-run without auth for reply/forward commands
Skip auth and message fetch when --dry-run is set by using placeholder
OriginalMessage data. This lets users preview the request structure
without needing credentials.
* fix(gmail): use RFC-aware mailbox list parsing for recipient splitting
Replace naive comma-split with split_mailbox_list that respects
quoted strings, so display names containing commas like
"Doe, John" <john@example.com> are handled correctly in reply-all
recipient parsing, deduplication, and --remove filtering.
* fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting
for backslash-escaped quotes (`\"`), causing display names like
`"Doe \"JD, Sr\""` to split incorrectly at interior commas.
Track `prev_backslash` so `\"` inside quoted strings is treated as a
literal quote character rather than a delimiter toggle. Double
backslashes (`\\`) are handled correctly as well.
* fix(gmail): address PR review feedback for reply/forward helpers
- Use reqwest .query() for metadata params per AGENTS.md convention
- Add MIME-Version and Content-Type headers to raw messages
- Add --from flag to +reply, +reply-all, +forward for send-as/alias
- Narrow ReplyConfig/ForwardConfig visibility to pub(super)
- Refactor create_reply_raw_message args into ReplyEnvelope struct
* fix(gmail): address review feedback for reply/forward helpers
- Exclude authenticated user's own email from reply-all CC by
fetching user profile via Gmail API
- Use format=full to extract full plain-text body instead of
truncated snippet for quoting and forwarding
- Deduplicate CC addresses using a HashSet
- Reuse auth token from message fetch in send_raw_email to
eliminate double auth round-trip
- Propagate auth errors in send_raw_email instead of silently
falling back to unauthenticated requests
- Use consistent CRLF line endings in quoted and forwarded
message bodies per RFC 2822
* fix(gmail): Gmail reply and forward helpers
* fix(gmail): refactor shared reply-forward helpers
* Preserve repeated Gmail address headers
* chore: regenerate skills [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jun 30, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 2, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 11, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Aug 6, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

18 participants

@zkat@booc0mtaco@aeschright@slavafomin@maartenvanbenthem@bakkot@maartenba@iarna@kemitchell@RobertKielty@scotttrinh@larsgw@hugovk@alopezsanchez@macdja38@seishun@kjin@kitayoshi
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Release: npm@6.5.0 - #105

Merged
zkat merged 47 commits into
latestfrom
release-next
Dec 10, 2018
Merged

Release: npm@6.5.0#105
zkat merged 47 commits into
latestfrom
release-next

Conversation

@zkat

@zkatzkat commented Nov 28, 2018

Copy link
Copy Markdown
Contributor

bakkotand others added 30 commits August 29, 2018 11:40
Oops: 7984206 did the
wrong thing with the git params, and it breaks anyone
trying to sign their git commits with npm version.
Fixes: https://npm.community/t/1661
Credit: @zkat
Fix browser opening under Windows Subsystem for Linux (WSL).
Credit: @thijsputman
With some tests I note npm use default branch of repository instead of `master`.
PR-URL: #64
Credit: @zckrs
Reviewed-By: @zkat
I found this page useful for setting up npm command completion. Thank you npm documentation team.
This suggested changed is based on my system which runs Ubuntu where
the completion directory path for bash is found in /etc/bash_completion.d and not /usr/local/etc/bash_completion.d
I dug around docs for this in The Bash Manual https://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion and on some an old (sadly retired) Debian Admin Site
https://debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
which seemed supportive of the dir being in /etc but I do not have access to an OS X machine where I guess bash_completion.d could be in /usr/local/etc so I left it in.
PR-URL: #72
Credit: @RobertKielty
Reviewed-By: @zkat
See discussion here: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
TL;DR:
> To be clear, you can specify an existing tag and it’ll change it. If you have 2FA enabled, you do need to specify `--otp` and if you don’t, you should get a `401` as above.
Ref: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
PR-URL: #74
Credit: @scotttrinh
Reviewed-By: @iarna
Reviewed-By: @zkat
* edit: fix handling of scoped packages
* edit: fix usage info
* docs: fix docs for the npm-edit command
PR-URL: #75
Credit: @larsgw
Reviewed-By: @iarna
PR-URL: #78
Credit: @hugovk
Reviewed-By: @zkat
This fixes https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3 and the other dozen or so issues that that link references, and possibly many more involving poor error messages from errors thrown by the upload function. @zkat you mentioned you could take a look at any fixes / answer any questions, if you could look this over and let me know if this is a good / valid approach that would be fantastic, thanks! (it wasn't a race condition, luckily :P).
it may also be helpful to add something like ```
if (!auth.token || !(auth.username && auth.password)) {
log.warn('publish', 'not logged in')
}
```
just before we even open the first file descriptor to make sure that even if the error message is completely wrong something in the log will give users a clue what may be going on. I took the method of looking for login creds from the logout method, I'm not sure that's valid or if alternatives to npm exist that don't require credentials but users could still publish to.
Triage of the issue:
1. The upload function throws an error
2. As that error bubbles through [cacache](https://www.npmjs.com/package/cacache#with-tmp) it tries to delete the tmpdir as it should
3. It can't delete the temp dir as the upload function's readFileStream to the tar it was trying to upload is still open.
4. [cacache](https://www.npmjs.com/package/cacache#with-tmp) throws an error about it's inability to remove the dir, which suppresses the upload function's error.
Fixes: https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3
PR-URL: #80
Credit: @macdja38
Reviewed-By: @zkat
* feat(cli, outdated): Adds 'Homepage' to outdated --long output.
- `package.json`'s `homepage` property is displayed when using the `--long` option for `npm outdated`
* test: npm outdated --long
- Adds `homepage` to `--parseable` output.
- Updates `npm outdated --long` test to include `homepage` in expected output.
- Adds `homepage` to `npm-outdated` documentation.
* fix: javascript standard style updates
PR-URL: #81
Credit: @jbottigliero
Reviewed-By: @zkat
… publish (#83)
Not sure when `--dry-run` was introduced, I assume it was introduced in npm 6 (correct me if I'm wrong). Anyway, hopefully this will prevent future developers from making the mistake of using it in npm 5 (like I did).
PR-URL: #83
Credit: @kjin
Reviewed-By: @zkat
@booc0mtaco

Copy link
Copy Markdown

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

@aeschright

Copy link
Copy Markdown
Contributor

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

Fixed in #96 for this release.

iarnaand others added 9 commits December 6, 2018 16:36
setuid() can not accept a 'nobody' parameter on IBM i.
The default user (QSECOFR) on IBM i has user id 0.
PR-URL: #65
Credit: @dmabupt
Reviewed-By: @zkat
Pass git binary path config to pacote.
Ref: zkat/pacote#164
Fixes: https://npm.community/t/3278
PR-URL: #98
Credit: @larsgw
Reviewed-By: @zkat
I keep typing `npm dist-tags` expecting it to print out a list of
dist-tags and instead it yells at me and that feels very un-npm-y.
PR-URL: #106
Credit: @isaacs
Reviewed-By: @zkat
@zkat
zkat merged commit 90e55a1 into latestDec 10, 2018
Jah-yee pushed a commit to Jah-yee/cli that referenced this pull request Apr 16, 2026
* feat(gmail): add +reply, +reply-all, and +forward helper commands
Add first-class reply and forward support to the Gmail helpers,
addressing the gap described in npm#88. These commands handle the
complex RFC 2822 threading mechanics (In-Reply-To, References,
threadId) that agents and CLI users struggle with today.
New commands:
- +reply: reply to a message with automatic threading
- +reply-all: reply to all recipients with --remove/--cc support
- +forward: forward a message with quoted original content
* fix(gmail): encode message_id in URL path and fix auth signature
- Use crate::validate::encode_path_segment() on message_id in
fetch_message_metadata URL construction per AGENTS.md rules
- Update auth::get_token calls to pass None for the new account
parameter added on main
* refactor(gmail): extract send_raw_email and deduplicate handlers
- Add send_raw_email() to mod.rs: shared encode→json→auth→execute
pattern for sending raw RFC 2822 messages via users.messages.send
- Simplify handle_reply: delegate send logic to send_raw_email
- Simplify handle_forward: delegate send logic to send_raw_email
Addresses code duplication feedback from PR review.
* fix(gmail): register --dry-run flag on reply/forward commands
The handlers read matches.get_flag("dry-run") but the flag was missing
from the clap command definitions, so it always returned false. Now
dry-run works for +reply, +reply-all, and +forward.
* chore: add changeset for gmail reply/forward feature
* style: apply cargo fmt formatting
* fix(gmail): register --dry-run flag on +send command
Same class of bug fixed for +reply/+reply-all/+forward — the handler
reads matches.get_flag("dry-run") but the arg was not registered.
* fix(gmail): honor Reply-To header and use exact address matching
- Prefer Reply-To over From when selecting reply recipients, fixing
incorrect routing for mailing lists and support systems
- Use exact email address comparison instead of substring matching
for --remove filtering and sender deduplication, preventing
unintended recipient removal (e.g. ann@ no longer drops joann@)
* test(gmail): add comprehensive coverage for reply address handling
- extract_email: malformed input (no closing bracket), empty string,
whitespace-only
- build_reply_all_recipients: display-name sender exclusion,
--remove with display name, extra --cc, CC becomes None when all
filtered, case-insensitive sender exclusion
* Improves reply-all recipient deduplication
Corrects how `build_reply_all_recipients` handles multi-address `Reply-To` headers.
Previously, only the first address from `Reply-To` was used for deduplication, leading to potential redundancy by including those addresses in the `Cc` field.
The updated logic now parses all addresses in `Reply-To`, ensuring they are fully moved to the `To` field and properly excluded from `Cc`.
* style(gmail): add missing Apache 2.0 copyright headers
reply.rs and forward.rs were missing the copyright header that all
other source files in the repo include.
* fix(gmail): use try_get_one for optional --remove arg in +reply
parse_reply_args used get_one("remove") which panics when called
from +reply (which does not register --remove). Switch to
try_get_one to safely return None for unregistered args.
* feat(gmail): support --dry-run without auth for reply/forward commands
Skip auth and message fetch when --dry-run is set by using placeholder
OriginalMessage data. This lets users preview the request structure
without needing credentials.
* fix(gmail): use RFC-aware mailbox list parsing for recipient splitting
Replace naive comma-split with split_mailbox_list that respects
quoted strings, so display names containing commas like
"Doe, John" <john@example.com> are handled correctly in reply-all
recipient parsing, deduplication, and --remove filtering.
* fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting
for backslash-escaped quotes (`\"`), causing display names like
`"Doe \"JD, Sr\""` to split incorrectly at interior commas.
Track `prev_backslash` so `\"` inside quoted strings is treated as a
literal quote character rather than a delimiter toggle. Double
backslashes (`\\`) are handled correctly as well.
* fix(gmail): address PR review feedback for reply/forward helpers
- Use reqwest .query() for metadata params per AGENTS.md convention
- Add MIME-Version and Content-Type headers to raw messages
- Add --from flag to +reply, +reply-all, +forward for send-as/alias
- Narrow ReplyConfig/ForwardConfig visibility to pub(super)
- Refactor create_reply_raw_message args into ReplyEnvelope struct
* fix(gmail): address review feedback for reply/forward helpers
- Exclude authenticated user's own email from reply-all CC by
fetching user profile via Gmail API
- Use format=full to extract full plain-text body instead of
truncated snippet for quoting and forwarding
- Deduplicate CC addresses using a HashSet
- Reuse auth token from message fetch in send_raw_email to
eliminate double auth round-trip
- Propagate auth errors in send_raw_email instead of silently
falling back to unauthenticated requests
- Use consistent CRLF line endings in quoted and forwarded
message bodies per RFC 2822
* fix(gmail): Gmail reply and forward helpers
* fix(gmail): refactor shared reply-forward helpers
* Preserve repeated Gmail address headers
* chore: regenerate skills [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jun 30, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 2, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 11, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Aug 6, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

18 participants

@zkat@booc0mtaco@aeschright@slavafomin@maartenvanbenthem@bakkot@maartenba@iarna@kemitchell@RobertKielty@scotttrinh@larsgw@hugovk@alopezsanchez@macdja38@seishun@kjin@kitayoshi
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Release: npm@6.5.0 - #105

Merged
zkat merged 47 commits into
latestfrom
release-next
Dec 10, 2018
Merged

Release: npm@6.5.0#105
zkat merged 47 commits into
latestfrom
release-next

Conversation

@zkat

@zkatzkat commented Nov 28, 2018

Copy link
Copy Markdown
Contributor

bakkotand others added 30 commits August 29, 2018 11:40
Oops: 7984206 did the
wrong thing with the git params, and it breaks anyone
trying to sign their git commits with npm version.
Fixes: https://npm.community/t/1661
Credit: @zkat
Fix browser opening under Windows Subsystem for Linux (WSL).
Credit: @thijsputman
With some tests I note npm use default branch of repository instead of `master`.
PR-URL: #64
Credit: @zckrs
Reviewed-By: @zkat
I found this page useful for setting up npm command completion. Thank you npm documentation team.
This suggested changed is based on my system which runs Ubuntu where
the completion directory path for bash is found in /etc/bash_completion.d and not /usr/local/etc/bash_completion.d
I dug around docs for this in The Bash Manual https://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion and on some an old (sadly retired) Debian Admin Site
https://debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
which seemed supportive of the dir being in /etc but I do not have access to an OS X machine where I guess bash_completion.d could be in /usr/local/etc so I left it in.
PR-URL: #72
Credit: @RobertKielty
Reviewed-By: @zkat
See discussion here: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
TL;DR:
> To be clear, you can specify an existing tag and it’ll change it. If you have 2FA enabled, you do need to specify `--otp` and if you don’t, you should get a `401` as above.
Ref: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
PR-URL: #74
Credit: @scotttrinh
Reviewed-By: @iarna
Reviewed-By: @zkat
* edit: fix handling of scoped packages
* edit: fix usage info
* docs: fix docs for the npm-edit command
PR-URL: #75
Credit: @larsgw
Reviewed-By: @iarna
PR-URL: #78
Credit: @hugovk
Reviewed-By: @zkat
This fixes https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3 and the other dozen or so issues that that link references, and possibly many more involving poor error messages from errors thrown by the upload function. @zkat you mentioned you could take a look at any fixes / answer any questions, if you could look this over and let me know if this is a good / valid approach that would be fantastic, thanks! (it wasn't a race condition, luckily :P).
it may also be helpful to add something like ```
if (!auth.token || !(auth.username && auth.password)) {
log.warn('publish', 'not logged in')
}
```
just before we even open the first file descriptor to make sure that even if the error message is completely wrong something in the log will give users a clue what may be going on. I took the method of looking for login creds from the logout method, I'm not sure that's valid or if alternatives to npm exist that don't require credentials but users could still publish to.
Triage of the issue:
1. The upload function throws an error
2. As that error bubbles through [cacache](https://www.npmjs.com/package/cacache#with-tmp) it tries to delete the tmpdir as it should
3. It can't delete the temp dir as the upload function's readFileStream to the tar it was trying to upload is still open.
4. [cacache](https://www.npmjs.com/package/cacache#with-tmp) throws an error about it's inability to remove the dir, which suppresses the upload function's error.
Fixes: https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3
PR-URL: #80
Credit: @macdja38
Reviewed-By: @zkat
* feat(cli, outdated): Adds 'Homepage' to outdated --long output.
- `package.json`'s `homepage` property is displayed when using the `--long` option for `npm outdated`
* test: npm outdated --long
- Adds `homepage` to `--parseable` output.
- Updates `npm outdated --long` test to include `homepage` in expected output.
- Adds `homepage` to `npm-outdated` documentation.
* fix: javascript standard style updates
PR-URL: #81
Credit: @jbottigliero
Reviewed-By: @zkat
… publish (#83)
Not sure when `--dry-run` was introduced, I assume it was introduced in npm 6 (correct me if I'm wrong). Anyway, hopefully this will prevent future developers from making the mistake of using it in npm 5 (like I did).
PR-URL: #83
Credit: @kjin
Reviewed-By: @zkat
@booc0mtaco

Copy link
Copy Markdown

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

@aeschright

Copy link
Copy Markdown
Contributor

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

Fixed in #96 for this release.

iarnaand others added 9 commits December 6, 2018 16:36
setuid() can not accept a 'nobody' parameter on IBM i.
The default user (QSECOFR) on IBM i has user id 0.
PR-URL: #65
Credit: @dmabupt
Reviewed-By: @zkat
Pass git binary path config to pacote.
Ref: zkat/pacote#164
Fixes: https://npm.community/t/3278
PR-URL: #98
Credit: @larsgw
Reviewed-By: @zkat
I keep typing `npm dist-tags` expecting it to print out a list of
dist-tags and instead it yells at me and that feels very un-npm-y.
PR-URL: #106
Credit: @isaacs
Reviewed-By: @zkat
@zkat
zkat merged commit 90e55a1 into latestDec 10, 2018
Jah-yee pushed a commit to Jah-yee/cli that referenced this pull request Apr 16, 2026
* feat(gmail): add +reply, +reply-all, and +forward helper commands
Add first-class reply and forward support to the Gmail helpers,
addressing the gap described in npm#88. These commands handle the
complex RFC 2822 threading mechanics (In-Reply-To, References,
threadId) that agents and CLI users struggle with today.
New commands:
- +reply: reply to a message with automatic threading
- +reply-all: reply to all recipients with --remove/--cc support
- +forward: forward a message with quoted original content
* fix(gmail): encode message_id in URL path and fix auth signature
- Use crate::validate::encode_path_segment() on message_id in
fetch_message_metadata URL construction per AGENTS.md rules
- Update auth::get_token calls to pass None for the new account
parameter added on main
* refactor(gmail): extract send_raw_email and deduplicate handlers
- Add send_raw_email() to mod.rs: shared encode→json→auth→execute
pattern for sending raw RFC 2822 messages via users.messages.send
- Simplify handle_reply: delegate send logic to send_raw_email
- Simplify handle_forward: delegate send logic to send_raw_email
Addresses code duplication feedback from PR review.
* fix(gmail): register --dry-run flag on reply/forward commands
The handlers read matches.get_flag("dry-run") but the flag was missing
from the clap command definitions, so it always returned false. Now
dry-run works for +reply, +reply-all, and +forward.
* chore: add changeset for gmail reply/forward feature
* style: apply cargo fmt formatting
* fix(gmail): register --dry-run flag on +send command
Same class of bug fixed for +reply/+reply-all/+forward — the handler
reads matches.get_flag("dry-run") but the arg was not registered.
* fix(gmail): honor Reply-To header and use exact address matching
- Prefer Reply-To over From when selecting reply recipients, fixing
incorrect routing for mailing lists and support systems
- Use exact email address comparison instead of substring matching
for --remove filtering and sender deduplication, preventing
unintended recipient removal (e.g. ann@ no longer drops joann@)
* test(gmail): add comprehensive coverage for reply address handling
- extract_email: malformed input (no closing bracket), empty string,
whitespace-only
- build_reply_all_recipients: display-name sender exclusion,
--remove with display name, extra --cc, CC becomes None when all
filtered, case-insensitive sender exclusion
* Improves reply-all recipient deduplication
Corrects how `build_reply_all_recipients` handles multi-address `Reply-To` headers.
Previously, only the first address from `Reply-To` was used for deduplication, leading to potential redundancy by including those addresses in the `Cc` field.
The updated logic now parses all addresses in `Reply-To`, ensuring they are fully moved to the `To` field and properly excluded from `Cc`.
* style(gmail): add missing Apache 2.0 copyright headers
reply.rs and forward.rs were missing the copyright header that all
other source files in the repo include.
* fix(gmail): use try_get_one for optional --remove arg in +reply
parse_reply_args used get_one("remove") which panics when called
from +reply (which does not register --remove). Switch to
try_get_one to safely return None for unregistered args.
* feat(gmail): support --dry-run without auth for reply/forward commands
Skip auth and message fetch when --dry-run is set by using placeholder
OriginalMessage data. This lets users preview the request structure
without needing credentials.
* fix(gmail): use RFC-aware mailbox list parsing for recipient splitting
Replace naive comma-split with split_mailbox_list that respects
quoted strings, so display names containing commas like
"Doe, John" <john@example.com> are handled correctly in reply-all
recipient parsing, deduplication, and --remove filtering.
* fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting
for backslash-escaped quotes (`\"`), causing display names like
`"Doe \"JD, Sr\""` to split incorrectly at interior commas.
Track `prev_backslash` so `\"` inside quoted strings is treated as a
literal quote character rather than a delimiter toggle. Double
backslashes (`\\`) are handled correctly as well.
* fix(gmail): address PR review feedback for reply/forward helpers
- Use reqwest .query() for metadata params per AGENTS.md convention
- Add MIME-Version and Content-Type headers to raw messages
- Add --from flag to +reply, +reply-all, +forward for send-as/alias
- Narrow ReplyConfig/ForwardConfig visibility to pub(super)
- Refactor create_reply_raw_message args into ReplyEnvelope struct
* fix(gmail): address review feedback for reply/forward helpers
- Exclude authenticated user's own email from reply-all CC by
fetching user profile via Gmail API
- Use format=full to extract full plain-text body instead of
truncated snippet for quoting and forwarding
- Deduplicate CC addresses using a HashSet
- Reuse auth token from message fetch in send_raw_email to
eliminate double auth round-trip
- Propagate auth errors in send_raw_email instead of silently
falling back to unauthenticated requests
- Use consistent CRLF line endings in quoted and forwarded
message bodies per RFC 2822
* fix(gmail): Gmail reply and forward helpers
* fix(gmail): refactor shared reply-forward helpers
* Preserve repeated Gmail address headers
* chore: regenerate skills [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jun 30, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 2, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 11, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Aug 6, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

18 participants

@zkat@booc0mtaco@aeschright@slavafomin@maartenvanbenthem@bakkot@maartenba@iarna@kemitchell@RobertKielty@scotttrinh@larsgw@hugovk@alopezsanchez@macdja38@seishun@kjin@kitayoshi
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Release: npm@6.5.0 - #105

Merged
zkat merged 47 commits into
latestfrom
release-next
Dec 10, 2018
Merged

Release: npm@6.5.0#105
zkat merged 47 commits into
latestfrom
release-next

Conversation

@zkat

@zkatzkat commented Nov 28, 2018

Copy link
Copy Markdown
Contributor

bakkotand others added 30 commits August 29, 2018 11:40
Oops: 7984206 did the
wrong thing with the git params, and it breaks anyone
trying to sign their git commits with npm version.
Fixes: https://npm.community/t/1661
Credit: @zkat
Fix browser opening under Windows Subsystem for Linux (WSL).
Credit: @thijsputman
With some tests I note npm use default branch of repository instead of `master`.
PR-URL: #64
Credit: @zckrs
Reviewed-By: @zkat
I found this page useful for setting up npm command completion. Thank you npm documentation team.
This suggested changed is based on my system which runs Ubuntu where
the completion directory path for bash is found in /etc/bash_completion.d and not /usr/local/etc/bash_completion.d
I dug around docs for this in The Bash Manual https://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion and on some an old (sadly retired) Debian Admin Site
https://debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
which seemed supportive of the dir being in /etc but I do not have access to an OS X machine where I guess bash_completion.d could be in /usr/local/etc so I left it in.
PR-URL: #72
Credit: @RobertKielty
Reviewed-By: @zkat
See discussion here: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
TL;DR:
> To be clear, you can specify an existing tag and it’ll change it. If you have 2FA enabled, you do need to specify `--otp` and if you don’t, you should get a `401` as above.
Ref: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
PR-URL: #74
Credit: @scotttrinh
Reviewed-By: @iarna
Reviewed-By: @zkat
* edit: fix handling of scoped packages
* edit: fix usage info
* docs: fix docs for the npm-edit command
PR-URL: #75
Credit: @larsgw
Reviewed-By: @iarna
PR-URL: #78
Credit: @hugovk
Reviewed-By: @zkat
This fixes https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3 and the other dozen or so issues that that link references, and possibly many more involving poor error messages from errors thrown by the upload function. @zkat you mentioned you could take a look at any fixes / answer any questions, if you could look this over and let me know if this is a good / valid approach that would be fantastic, thanks! (it wasn't a race condition, luckily :P).
it may also be helpful to add something like ```
if (!auth.token || !(auth.username && auth.password)) {
log.warn('publish', 'not logged in')
}
```
just before we even open the first file descriptor to make sure that even if the error message is completely wrong something in the log will give users a clue what may be going on. I took the method of looking for login creds from the logout method, I'm not sure that's valid or if alternatives to npm exist that don't require credentials but users could still publish to.
Triage of the issue:
1. The upload function throws an error
2. As that error bubbles through [cacache](https://www.npmjs.com/package/cacache#with-tmp) it tries to delete the tmpdir as it should
3. It can't delete the temp dir as the upload function's readFileStream to the tar it was trying to upload is still open.
4. [cacache](https://www.npmjs.com/package/cacache#with-tmp) throws an error about it's inability to remove the dir, which suppresses the upload function's error.
Fixes: https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3
PR-URL: #80
Credit: @macdja38
Reviewed-By: @zkat
* feat(cli, outdated): Adds 'Homepage' to outdated --long output.
- `package.json`'s `homepage` property is displayed when using the `--long` option for `npm outdated`
* test: npm outdated --long
- Adds `homepage` to `--parseable` output.
- Updates `npm outdated --long` test to include `homepage` in expected output.
- Adds `homepage` to `npm-outdated` documentation.
* fix: javascript standard style updates
PR-URL: #81
Credit: @jbottigliero
Reviewed-By: @zkat
… publish (#83)
Not sure when `--dry-run` was introduced, I assume it was introduced in npm 6 (correct me if I'm wrong). Anyway, hopefully this will prevent future developers from making the mistake of using it in npm 5 (like I did).
PR-URL: #83
Credit: @kjin
Reviewed-By: @zkat
@booc0mtaco

Copy link
Copy Markdown

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

@aeschright

Copy link
Copy Markdown
Contributor

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

Fixed in #96 for this release.

iarnaand others added 9 commits December 6, 2018 16:36
setuid() can not accept a 'nobody' parameter on IBM i.
The default user (QSECOFR) on IBM i has user id 0.
PR-URL: #65
Credit: @dmabupt
Reviewed-By: @zkat
Pass git binary path config to pacote.
Ref: zkat/pacote#164
Fixes: https://npm.community/t/3278
PR-URL: #98
Credit: @larsgw
Reviewed-By: @zkat
I keep typing `npm dist-tags` expecting it to print out a list of
dist-tags and instead it yells at me and that feels very un-npm-y.
PR-URL: #106
Credit: @isaacs
Reviewed-By: @zkat
@zkat
zkat merged commit 90e55a1 into latestDec 10, 2018
Jah-yee pushed a commit to Jah-yee/cli that referenced this pull request Apr 16, 2026
* feat(gmail): add +reply, +reply-all, and +forward helper commands
Add first-class reply and forward support to the Gmail helpers,
addressing the gap described in npm#88. These commands handle the
complex RFC 2822 threading mechanics (In-Reply-To, References,
threadId) that agents and CLI users struggle with today.
New commands:
- +reply: reply to a message with automatic threading
- +reply-all: reply to all recipients with --remove/--cc support
- +forward: forward a message with quoted original content
* fix(gmail): encode message_id in URL path and fix auth signature
- Use crate::validate::encode_path_segment() on message_id in
fetch_message_metadata URL construction per AGENTS.md rules
- Update auth::get_token calls to pass None for the new account
parameter added on main
* refactor(gmail): extract send_raw_email and deduplicate handlers
- Add send_raw_email() to mod.rs: shared encode→json→auth→execute
pattern for sending raw RFC 2822 messages via users.messages.send
- Simplify handle_reply: delegate send logic to send_raw_email
- Simplify handle_forward: delegate send logic to send_raw_email
Addresses code duplication feedback from PR review.
* fix(gmail): register --dry-run flag on reply/forward commands
The handlers read matches.get_flag("dry-run") but the flag was missing
from the clap command definitions, so it always returned false. Now
dry-run works for +reply, +reply-all, and +forward.
* chore: add changeset for gmail reply/forward feature
* style: apply cargo fmt formatting
* fix(gmail): register --dry-run flag on +send command
Same class of bug fixed for +reply/+reply-all/+forward — the handler
reads matches.get_flag("dry-run") but the arg was not registered.
* fix(gmail): honor Reply-To header and use exact address matching
- Prefer Reply-To over From when selecting reply recipients, fixing
incorrect routing for mailing lists and support systems
- Use exact email address comparison instead of substring matching
for --remove filtering and sender deduplication, preventing
unintended recipient removal (e.g. ann@ no longer drops joann@)
* test(gmail): add comprehensive coverage for reply address handling
- extract_email: malformed input (no closing bracket), empty string,
whitespace-only
- build_reply_all_recipients: display-name sender exclusion,
--remove with display name, extra --cc, CC becomes None when all
filtered, case-insensitive sender exclusion
* Improves reply-all recipient deduplication
Corrects how `build_reply_all_recipients` handles multi-address `Reply-To` headers.
Previously, only the first address from `Reply-To` was used for deduplication, leading to potential redundancy by including those addresses in the `Cc` field.
The updated logic now parses all addresses in `Reply-To`, ensuring they are fully moved to the `To` field and properly excluded from `Cc`.
* style(gmail): add missing Apache 2.0 copyright headers
reply.rs and forward.rs were missing the copyright header that all
other source files in the repo include.
* fix(gmail): use try_get_one for optional --remove arg in +reply
parse_reply_args used get_one("remove") which panics when called
from +reply (which does not register --remove). Switch to
try_get_one to safely return None for unregistered args.
* feat(gmail): support --dry-run without auth for reply/forward commands
Skip auth and message fetch when --dry-run is set by using placeholder
OriginalMessage data. This lets users preview the request structure
without needing credentials.
* fix(gmail): use RFC-aware mailbox list parsing for recipient splitting
Replace naive comma-split with split_mailbox_list that respects
quoted strings, so display names containing commas like
"Doe, John" <john@example.com> are handled correctly in reply-all
recipient parsing, deduplication, and --remove filtering.
* fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting
for backslash-escaped quotes (`\"`), causing display names like
`"Doe \"JD, Sr\""` to split incorrectly at interior commas.
Track `prev_backslash` so `\"` inside quoted strings is treated as a
literal quote character rather than a delimiter toggle. Double
backslashes (`\\`) are handled correctly as well.
* fix(gmail): address PR review feedback for reply/forward helpers
- Use reqwest .query() for metadata params per AGENTS.md convention
- Add MIME-Version and Content-Type headers to raw messages
- Add --from flag to +reply, +reply-all, +forward for send-as/alias
- Narrow ReplyConfig/ForwardConfig visibility to pub(super)
- Refactor create_reply_raw_message args into ReplyEnvelope struct
* fix(gmail): address review feedback for reply/forward helpers
- Exclude authenticated user's own email from reply-all CC by
fetching user profile via Gmail API
- Use format=full to extract full plain-text body instead of
truncated snippet for quoting and forwarding
- Deduplicate CC addresses using a HashSet
- Reuse auth token from message fetch in send_raw_email to
eliminate double auth round-trip
- Propagate auth errors in send_raw_email instead of silently
falling back to unauthenticated requests
- Use consistent CRLF line endings in quoted and forwarded
message bodies per RFC 2822
* fix(gmail): Gmail reply and forward helpers
* fix(gmail): refactor shared reply-forward helpers
* Preserve repeated Gmail address headers
* chore: regenerate skills [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jun 30, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 2, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 11, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Aug 6, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

18 participants

@zkat@booc0mtaco@aeschright@slavafomin@maartenvanbenthem@bakkot@maartenba@iarna@kemitchell@RobertKielty@scotttrinh@larsgw@hugovk@alopezsanchez@macdja38@seishun@kjin@kitayoshi
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Release: npm@6.5.0 - #105

Merged
zkat merged 47 commits into
latestfrom
release-next
Dec 10, 2018
Merged

Release: npm@6.5.0#105
zkat merged 47 commits into
latestfrom
release-next

Conversation

@zkat

@zkatzkat commented Nov 28, 2018

Copy link
Copy Markdown
Contributor

bakkotand others added 30 commits August 29, 2018 11:40
Oops: 7984206 did the
wrong thing with the git params, and it breaks anyone
trying to sign their git commits with npm version.
Fixes: https://npm.community/t/1661
Credit: @zkat
Fix browser opening under Windows Subsystem for Linux (WSL).
Credit: @thijsputman
With some tests I note npm use default branch of repository instead of `master`.
PR-URL: #64
Credit: @zckrs
Reviewed-By: @zkat
I found this page useful for setting up npm command completion. Thank you npm documentation team.
This suggested changed is based on my system which runs Ubuntu where
the completion directory path for bash is found in /etc/bash_completion.d and not /usr/local/etc/bash_completion.d
I dug around docs for this in The Bash Manual https://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion and on some an old (sadly retired) Debian Admin Site
https://debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
which seemed supportive of the dir being in /etc but I do not have access to an OS X machine where I guess bash_completion.d could be in /usr/local/etc so I left it in.
PR-URL: #72
Credit: @RobertKielty
Reviewed-By: @zkat
See discussion here: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
TL;DR:
> To be clear, you can specify an existing tag and it’ll change it. If you have 2FA enabled, you do need to specify `--otp` and if you don’t, you should get a `401` as above.
Ref: https://npm.community/t/npm-dist-tag-add-with-2fa-enabled-fails-for-non-latest-tag-with-500/2432
PR-URL: #74
Credit: @scotttrinh
Reviewed-By: @iarna
Reviewed-By: @zkat
* edit: fix handling of scoped packages
* edit: fix usage info
* docs: fix docs for the npm-edit command
PR-URL: #75
Credit: @larsgw
Reviewed-By: @iarna
PR-URL: #78
Credit: @hugovk
Reviewed-By: @zkat
This fixes https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3 and the other dozen or so issues that that link references, and possibly many more involving poor error messages from errors thrown by the upload function. @zkat you mentioned you could take a look at any fixes / answer any questions, if you could look this over and let me know if this is a good / valid approach that would be fantastic, thanks! (it wasn't a race condition, luckily :P).
it may also be helpful to add something like ```
if (!auth.token || !(auth.username && auth.password)) {
log.warn('publish', 'not logged in')
}
```
just before we even open the first file descriptor to make sure that even if the error message is completely wrong something in the log will give users a clue what may be going on. I took the method of looking for login creds from the logout method, I'm not sure that's valid or if alternatives to npm exist that don't require credentials but users could still publish to.
Triage of the issue:
1. The upload function throws an error
2. As that error bubbles through [cacache](https://www.npmjs.com/package/cacache#with-tmp) it tries to delete the tmpdir as it should
3. It can't delete the temp dir as the upload function's readFileStream to the tar it was trying to upload is still open.
4. [cacache](https://www.npmjs.com/package/cacache#with-tmp) throws an error about it's inability to remove the dir, which suppresses the upload function's error.
Fixes: https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3
PR-URL: #80
Credit: @macdja38
Reviewed-By: @zkat
* feat(cli, outdated): Adds 'Homepage' to outdated --long output.
- `package.json`'s `homepage` property is displayed when using the `--long` option for `npm outdated`
* test: npm outdated --long
- Adds `homepage` to `--parseable` output.
- Updates `npm outdated --long` test to include `homepage` in expected output.
- Adds `homepage` to `npm-outdated` documentation.
* fix: javascript standard style updates
PR-URL: #81
Credit: @jbottigliero
Reviewed-By: @zkat
… publish (#83)
Not sure when `--dry-run` was introduced, I assume it was introduced in npm 6 (correct me if I'm wrong). Anyway, hopefully this will prevent future developers from making the mistake of using it in npm 5 (like I did).
PR-URL: #83
Credit: @kjin
Reviewed-By: @zkat
@booc0mtaco

Copy link
Copy Markdown

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

@aeschright

Copy link
Copy Markdown
Contributor

Hey there,

Was digging around, and spotted some busted formatting on a page.

https://docs.npmjs.com/misc/scripts

Breaking chunk is here, i think. perhaps <pkg> needs to be brought up to the previous line (or there's a bug in the markdown processor).

Fixed in #96 for this release.

iarnaand others added 9 commits December 6, 2018 16:36
setuid() can not accept a 'nobody' parameter on IBM i.
The default user (QSECOFR) on IBM i has user id 0.
PR-URL: #65
Credit: @dmabupt
Reviewed-By: @zkat
Pass git binary path config to pacote.
Ref: zkat/pacote#164
Fixes: https://npm.community/t/3278
PR-URL: #98
Credit: @larsgw
Reviewed-By: @zkat
I keep typing `npm dist-tags` expecting it to print out a list of
dist-tags and instead it yells at me and that feels very un-npm-y.
PR-URL: #106
Credit: @isaacs
Reviewed-By: @zkat
@zkat
zkat merged commit 90e55a1 into latestDec 10, 2018
Jah-yee pushed a commit to Jah-yee/cli that referenced this pull request Apr 16, 2026
* feat(gmail): add +reply, +reply-all, and +forward helper commands
Add first-class reply and forward support to the Gmail helpers,
addressing the gap described in npm#88. These commands handle the
complex RFC 2822 threading mechanics (In-Reply-To, References,
threadId) that agents and CLI users struggle with today.
New commands:
- +reply: reply to a message with automatic threading
- +reply-all: reply to all recipients with --remove/--cc support
- +forward: forward a message with quoted original content
* fix(gmail): encode message_id in URL path and fix auth signature
- Use crate::validate::encode_path_segment() on message_id in
fetch_message_metadata URL construction per AGENTS.md rules
- Update auth::get_token calls to pass None for the new account
parameter added on main
* refactor(gmail): extract send_raw_email and deduplicate handlers
- Add send_raw_email() to mod.rs: shared encode→json→auth→execute
pattern for sending raw RFC 2822 messages via users.messages.send
- Simplify handle_reply: delegate send logic to send_raw_email
- Simplify handle_forward: delegate send logic to send_raw_email
Addresses code duplication feedback from PR review.
* fix(gmail): register --dry-run flag on reply/forward commands
The handlers read matches.get_flag("dry-run") but the flag was missing
from the clap command definitions, so it always returned false. Now
dry-run works for +reply, +reply-all, and +forward.
* chore: add changeset for gmail reply/forward feature
* style: apply cargo fmt formatting
* fix(gmail): register --dry-run flag on +send command
Same class of bug fixed for +reply/+reply-all/+forward — the handler
reads matches.get_flag("dry-run") but the arg was not registered.
* fix(gmail): honor Reply-To header and use exact address matching
- Prefer Reply-To over From when selecting reply recipients, fixing
incorrect routing for mailing lists and support systems
- Use exact email address comparison instead of substring matching
for --remove filtering and sender deduplication, preventing
unintended recipient removal (e.g. ann@ no longer drops joann@)
* test(gmail): add comprehensive coverage for reply address handling
- extract_email: malformed input (no closing bracket), empty string,
whitespace-only
- build_reply_all_recipients: display-name sender exclusion,
--remove with display name, extra --cc, CC becomes None when all
filtered, case-insensitive sender exclusion
* Improves reply-all recipient deduplication
Corrects how `build_reply_all_recipients` handles multi-address `Reply-To` headers.
Previously, only the first address from `Reply-To` was used for deduplication, leading to potential redundancy by including those addresses in the `Cc` field.
The updated logic now parses all addresses in `Reply-To`, ensuring they are fully moved to the `To` field and properly excluded from `Cc`.
* style(gmail): add missing Apache 2.0 copyright headers
reply.rs and forward.rs were missing the copyright header that all
other source files in the repo include.
* fix(gmail): use try_get_one for optional --remove arg in +reply
parse_reply_args used get_one("remove") which panics when called
from +reply (which does not register --remove). Switch to
try_get_one to safely return None for unregistered args.
* feat(gmail): support --dry-run without auth for reply/forward commands
Skip auth and message fetch when --dry-run is set by using placeholder
OriginalMessage data. This lets users preview the request structure
without needing credentials.
* fix(gmail): use RFC-aware mailbox list parsing for recipient splitting
Replace naive comma-split with split_mailbox_list that respects
quoted strings, so display names containing commas like
"Doe, John" <john@example.com> are handled correctly in reply-all
recipient parsing, deduplication, and --remove filtering.
* fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting
for backslash-escaped quotes (`\"`), causing display names like
`"Doe \"JD, Sr\""` to split incorrectly at interior commas.
Track `prev_backslash` so `\"` inside quoted strings is treated as a
literal quote character rather than a delimiter toggle. Double
backslashes (`\\`) are handled correctly as well.
* fix(gmail): address PR review feedback for reply/forward helpers
- Use reqwest .query() for metadata params per AGENTS.md convention
- Add MIME-Version and Content-Type headers to raw messages
- Add --from flag to +reply, +reply-all, +forward for send-as/alias
- Narrow ReplyConfig/ForwardConfig visibility to pub(super)
- Refactor create_reply_raw_message args into ReplyEnvelope struct
* fix(gmail): address review feedback for reply/forward helpers
- Exclude authenticated user's own email from reply-all CC by
fetching user profile via Gmail API
- Use format=full to extract full plain-text body instead of
truncated snippet for quoting and forwarding
- Deduplicate CC addresses using a HashSet
- Reuse auth token from message fetch in send_raw_email to
eliminate double auth round-trip
- Propagate auth errors in send_raw_email instead of silently
falling back to unauthenticated requests
- Use consistent CRLF line endings in quoted and forwarded
message bodies per RFC 2822
* fix(gmail): Gmail reply and forward helpers
* fix(gmail): refactor shared reply-forward helpers
* Preserve repeated Gmail address headers
* chore: regenerate skills [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jun 30, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 2, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Jul 11, 2026
github-actionsBot added a commit to Kevinlee7250/cli that referenced this pull request Aug 6, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

18 participants

@zkat@booc0mtaco@aeschright@slavafomin@maartenvanbenthem@bakkot@maartenba@iarna@kemitchell@RobertKielty@scotttrinh@larsgw@hugovk@alopezsanchez@macdja38@seishun@kjin@kitayoshi