Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions nowledge-mem-browse-now-npx-skills/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

All notable changes to the Browse Now npx skill package will be documented in this file.

## [0.1.0] - 2026-03-10

### Added

- Initial reusable `browse-now` skill package for `npx skills`
- README covering app, extension, and browser requirements
- Skill guidance for refs-first interaction, navigation verification, and authenticated browser work
77 changes: 77 additions & 0 deletions nowledge-mem-browse-now-npx-skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Browse Now Skill for AI Agents

> Install a reusable `browse-now` skill on supported AI coding agents with `npx skills add`.

This package teaches compatible agents how to use the `browse-now` CLI that ships with the Nowledge Mem desktop app.

`browse-now` controls the user's real browser through the Nowledge Mem Exchange extension. It is the right tool for authenticated websites, dynamic pages, form filling, screenshots, and browser flows that ordinary web search cannot reach.

This is a local-only capability. The CLI, the Nowledge Mem app, the connected browser, and the extension must live on the same machine. Access Anywhere does not expose the browser bridge.

## Install

```bash
npx skills add nowledge-co/community/nowledge-mem-browse-now-npx-skills
```

Install just this skill:

```bash
npx skills add nowledge-co/community/nowledge-mem-browse-now-npx-skills --skill browse-now
```

## Requirements

You need all of these:

- the Nowledge Mem desktop app installed
- the bundled `browse-now` CLI available on your machine
- the Nowledge Mem Exchange browser extension installed in Chrome, Edge, Arc, or another supported Chromium browser
- at least one connected browser with the extension active

If the app is installed, `browse-now` is normally auto-installed for you. Verify with:

```bash
browse-now status
browse-now --help
```

If no browser is connected yet, open the browser where the extension is installed and keep the extension active.

## What The Skill Does

After installation, the agent learns to:

- prefer `browse-now` for authenticated and interactive browser work
- use refs from `snapshot -i` as the primary interaction surface
- re-snapshot after navigation or DOM changes
- verify navigation with `browse-now get url` or `browse-now get title`
- fall back to text clicks or screenshots when accessibility data is sparse

## Quick Start

```bash
browse-now open https://example.com
browse-now snapshot -i
browse-now click @e5
browse-now fill @e3 "search query" --submit
browse-now get page-text --max-chars 3000
```

## When To Use It

Use `browse-now` when the task requires:

- a logged-in website
- a real browser session with the user's cookies
- clicking, typing, or navigating through a live UI
- screenshots or visual follow-up on image-heavy pages
- content extraction from dynamic sites that do not expose enough text to normal search tools

Do not use it for simple public lookups that ordinary web search can answer faster.

## Links

- [Browse Now documentation](https://mem.nowledge.co/docs/browse-now)
- [Nowledge Mem](https://mem.nowledge.co)
- [Nowledge Mem Exchange](https://github.com/nowledge-co/nowledge-mem-exchange)
66 changes: 66 additions & 0 deletions nowledge-mem-browse-now-npx-skills/skills/browse-now/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
name: browse-now
description: Control the user's actual browser through the browse-now CLI when a task needs authenticated pages, dynamic interaction, form filling, screenshots, or other browser automation that web search cannot reach. Prefer it whenever the task depends on the user's real browser state rather than a generic fetch.
---

# Browse Now

> Use the user's real browser when the task needs live interaction, login state, or dynamic content.

## When To Use

Use `browse-now` when:

- the site requires the user's existing browser session or login cookies
- the task needs clicking, typing, scrolling, or navigating through a live page
- the page is dynamic enough that plain HTTP fetches or web search will miss the real UI state
- the user needs a screenshot or content extraction from the rendered page

Skip it when ordinary web search or direct HTTP fetching would answer the question faster.

`browse-now` is local-only. It must run on the same machine as the Nowledge Mem app, the browser, and the Exchange extension. It is not exposed through Access Anywhere.

## Core Loop

```bash
browse-now open <url>
browse-now snapshot -i
browse-now click @e5
browse-now wait 2
browse-now get url
browse-now snapshot -i
```

## Preferred Interaction Order

1. Start with `browse-now snapshot -i` to get interactive refs.
2. Use `click @eN` and `fill @eN ...` as the primary interaction path.
3. After navigation or major DOM changes, run `snapshot -i` again because refs reset.
4. Confirm page changes with `browse-now get url` or `browse-now get title`.
5. If accessibility data is sparse, use `browse-now find "query"`, `click -T "text"`, or `screenshot`.

## Practical Commands

```bash
browse-now open https://example.com
browse-now snapshot -i
browse-now find "login button"
browse-now click @e12
browse-now fill @e3 "search text" --submit
browse-now get page-text --max-chars 4000
browse-now screenshot /tmp/page.png
```

## Reliability Notes

- Refs from `snapshot -i` are the most reliable click targets.
- Text clicks are a fallback for dialogs, dropdowns, or poor accessibility trees.
- A successful click does not bypass login walls, paywalls, or anti-bot behavior.
- Always verify where you landed before assuming the browser action failed.

## Requirements

- Nowledge Mem desktop app installed
- `browse-now` available on `PATH`
- Nowledge Mem Exchange extension installed in a supported browser
- A connected browser session the agent can control
12 changes: 12 additions & 0 deletions nowledge-mem-gemini-cli-extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ All notable changes to the Nowledge Mem Gemini CLI extension will be documented
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.2] - 2026-03-10

### Changed

- Hardened the Gemini release packaging flow so the shipped archive better matches what the marketplace crawler expects from a clean extension bundle
- Refined release instructions to explicitly call out archive verification for macOS metadata drift before publishing

### Fixed

- Prevented macOS AppleDouble metadata entries such as `._README.md` from being emitted into the release archive
- Added archive verification that fails packaging if hidden metadata files still appear in the generated `.tar.gz`

## [0.1.1] - 2026-03-09

### Changed
Expand Down
14 changes: 8 additions & 6 deletions nowledge-mem-gemini-cli-extension/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ These are required for Gemini's gallery crawler, but cannot be enforced purely b
- the repository About section must include the `gemini-cli-extension` topic
- the release must be tagged and published on GitHub
- the attached archive must contain `gemini-extension.json` at the archive root
- the attached archive must be free of macOS AppleDouble metadata entries such as `._README.md`

## Validate Locally

Expand Down Expand Up @@ -63,25 +64,25 @@ nowledge-mem-gemini-cli-extension-v*
Example:

```bash
git tag nowledge-mem-gemini-cli-extension-v0.1.1
git push origin nowledge-mem-gemini-cli-extension-v0.1.1
git tag nowledge-mem-gemini-cli-extension-v0.1.2
git push origin nowledge-mem-gemini-cli-extension-v0.1.2
```

## Initial Public Release

For the first public release, use:

- tag: `nowledge-mem-gemini-cli-extension-v0.1.1`
- release title: `Nowledge Mem Gemini CLI Extension v0.1.1`
- release notes source: `release-notes/0.1.1.md`
- tag: `nowledge-mem-gemini-cli-extension-v0.1.2`
- release title: `Nowledge Mem Gemini CLI Extension v0.1.2`
- release notes source: `release-notes/0.1.2.md`
- workflow behavior: the release workflow verifies that the pushed tag matches `package.json` and publishes the matching `release-notes/<version>.md` file as the GitHub Release body

## Installation After Release

Once the tagged GitHub Release exists, Gemini users can install from the repository and ref:

```bash
gemini extensions install github.com/nowledge-co/community --ref nowledge-mem-gemini-cli-extension-v0.1.1
gemini extensions install github.com/nowledge-co/community --ref nowledge-mem-gemini-cli-extension-v0.1.2
```

Gemini's own release docs say GitHub Releases are supported as install sources, and the workflow-created archive is shaped specifically for that path.
Expand All @@ -96,4 +97,5 @@ Gemini's own release docs say GitHub Releases are supported as install sources,
- create and push a matching tag
- publish the GitHub Release with the generated `.tar.gz` asset and checksum
- verify the repo still has the `gemini-cli-extension` topic
- verify the archive contents with `tar -tzf dist/nowledge-mem-gemini-cli-extension.tar.gz` and make sure there are no `._*` entries
- verify discovery on `geminicli.com/extensions` after the crawler runs
2 changes: 1 addition & 1 deletion nowledge-mem-gemini-cli-extension/gemini-extension.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nowledge-mem-gemini-cli-extension",
"version": "0.1.1",
"version": "0.1.2",
"description": "Gemini CLI extension for Nowledge Mem with persistent context, memory commands, and agent skills.",
"contextFileName": "GEMINI.md"
}
2 changes: 1 addition & 1 deletion nowledge-mem-gemini-cli-extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nowledge-mem-gemini-cli-extension",
"version": "0.1.1",
"version": "0.1.2",
"private": true,
"description": "Gemini CLI extension for Nowledge Mem",
"license": "MIT",
Expand Down
21 changes: 21 additions & 0 deletions nowledge-mem-gemini-cli-extension/release-notes/0.1.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Nowledge Mem Gemini CLI Extension v0.1.2

Release packaging hardening update for the Gemini CLI extension.

## Summary

- Prevents macOS AppleDouble metadata files from leaking into the published release archive.
- Fails packaging early if hidden metadata entries still appear, so bad archives are caught before tagging or upload.
- Tightens the release checklist and examples so the GitHub Release asset matches what Gemini marketplace discovery expects.

## Operational Notes

- Run `npm run verify:release` before tagging.
- Publish the generated `.tar.gz` plus checksum from `dist/`.
- Keep using the matching tag name `nowledge-mem-gemini-cli-extension-v0.1.2`.

## Install

```bash
gemini extensions install github.com/nowledge-co/community --ref nowledge-mem-gemini-cli-extension-v0.1.2
```
31 changes: 25 additions & 6 deletions nowledge-mem-gemini-cli-extension/scripts/package-extension.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,26 @@ function verifyArchive(filePath) {
process.exit(result.status ?? 1);
}

const rawEntries = result.stdout
.split('\n')
.map((line) => line.trim())
.filter(Boolean);

const entries = new Set(
result.stdout
.split('\n')
.map((line) => line.trim())
.filter(Boolean)
rawEntries.map((line) => {
if (line === '.') return './';
return line.startsWith('./') ? line : `./${line}`;
})
);

for (const entry of rawEntries) {
const normalized = entry.startsWith('./') ? entry.slice(2) : entry;
if (normalized === '._.' || normalized.startsWith('._') || normalized.includes('/._')) {
console.error(`ERROR: release archive contains macOS metadata entry ${entry}`);
process.exit(1);
}
}

for (const requiredEntry of requiredArchiveEntries) {
if (!entries.has(requiredEntry)) {
console.error(`ERROR: release archive is missing ${requiredEntry}`);
Expand All @@ -92,13 +105,19 @@ async function main() {
});
}

run('tar', ['-czf', archivePath, '-C', stageDir, '.']);
run('tar', ['-czf', archivePath, '-C', stageDir, '.'], extensionRoot, {
env: {
...process.env,
COPYFILE_DISABLE: '1'
}
});
verifyArchive(archivePath);

const checksum = await fileSha256(archivePath);
await writeFile(
path.join(distDir, `${archiveName}.sha256`),
`${checksum} ${archiveName}\n`,
`${checksum} ${archiveName}
`,
'utf8'
);

Expand Down