chore: import upstream snapshot with attribution
CI / test (20, macos-latest) (push) Waiting to run
CI / test (20, ubuntu-latest) (push) Waiting to run
CI / test (22, macos-latest) (push) Waiting to run
CI / test (22, ubuntu-latest) (push) Waiting to run

This commit is contained in:
wehub-resource-sync
2026-07-13 13:01:18 +08:00
commit 979fb22d7c
613 changed files with 113494 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
github: [rohitg00]
+110
View File
@@ -0,0 +1,110 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
day: monday
time: "06:00"
timezone: Etc/UTC
open-pull-requests-limit: 10
labels:
- dependencies
- npm
commit-message:
prefix: deps
include: scope
groups:
minor-and-patch:
update-types:
- minor
- patch
- package-ecosystem: npm
directory: /website
schedule:
interval: weekly
day: monday
time: "06:00"
timezone: Etc/UTC
open-pull-requests-limit: 10
labels:
- dependencies
- npm
- website
commit-message:
prefix: deps(website)
include: scope
groups:
minor-and-patch:
update-types:
- minor
- patch
- package-ecosystem: npm
directory: /integrations/openclaw
schedule:
interval: weekly
day: monday
time: "06:00"
timezone: Etc/UTC
open-pull-requests-limit: 5
labels:
- dependencies
- npm
- integrations
commit-message:
prefix: deps(openclaw)
include: scope
- package-ecosystem: npm
directory: /integrations/pi
schedule:
interval: weekly
day: monday
time: "06:00"
timezone: Etc/UTC
open-pull-requests-limit: 5
labels:
- dependencies
- npm
- integrations
commit-message:
prefix: deps(pi)
include: scope
- package-ecosystem: npm
directory: /integrations/filesystem-watcher
schedule:
interval: weekly
day: monday
time: "06:00"
timezone: Etc/UTC
open-pull-requests-limit: 5
labels:
- dependencies
- npm
- integrations
commit-message:
prefix: deps(fs-watcher)
include: scope
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: monday
time: "06:00"
timezone: Etc/UTC
open-pull-requests-limit: 5
labels:
- dependencies
- github-actions
commit-message:
prefix: ci(deps)
include: scope
groups:
minor-and-patch:
update-types:
- minor
- patch
@@ -0,0 +1,46 @@
# GHSA Draft: Stored XSS in agentmemory real-time viewer
**Severity:** Critical · **CVSS 3.1:** 9.6 (`AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L`)
**CWE:** [CWE-79 — Improper Neutralization of Input During Web Page Generation](https://cwe.mitre.org/data/definitions/79.html)
**Affected versions:** `< 0.8.2`
**Patched version:** `0.8.2`
## Summary
agentmemory's real-time viewer (default port 3113) rendered user-controlled data — tool outputs, file paths, memory titles, observation content — into HTML using inline `onclick=` event handlers. The viewer's Content Security Policy simultaneously allowed `script-src 'unsafe-inline'`, meaning injected JavaScript would execute in the reader's browser context.
## Impact
Any data captured by agentmemory hooks — which includes tool output from Claude Code, Cursor, or any other agent — becomes an XSS vector when the user opens the viewer. An attacker with the ability to influence any captured observation (e.g., by sending a crafted file contents to be read by an agent, or by planting a malicious commit message in a repository) could:
- Exfiltrate the entire memory store via authenticated requests from the browser
- Read `AGENTMEMORY_SECRET` if the viewer was configured with auth
- Make requests to arbitrary endpoints on behalf of the viewer user
- Modify the DOM to mislead the developer
- Pivot to other localhost services on the developer's machine
The viewer runs on localhost by default but is **reachable from the browser**, so standard same-origin protections don't help.
## Patches
Fixed in **0.8.2**:
- All inline `on*=` handlers removed from `src/viewer/index.html`
- Replaced with delegated `data-action` event handling
- CSP switched to a **per-response script nonce** (`script-src 'nonce-<random>'`)
- Added `script-src-attr 'none'` to block any inline handler attributes even if injected
- Viewer HTML now rendered through `src/viewer/document.ts` which generates a fresh nonce per request
## Workarounds
**None.** Users on affected versions should upgrade to 0.8.2 immediately. Do not open `http://localhost:3113` in a browser on affected versions if you suspect any of your captured observations may contain attacker-controlled content.
## References
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
- Reporter: @eng-pf
## Credit
@eng-pf submitted PR #108 with fixes for this and 5 other vulnerabilities.
@@ -0,0 +1,57 @@
# GHSA Draft: Remote shell script execution in agentmemory CLI startup
**Severity:** Critical · **CVSS 3.1:** 9.8 (`AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`)
**CWE:** [CWE-494 — Download of Code Without Integrity Check](https://cwe.mitre.org/data/definitions/494.html), [CWE-829 — Inclusion of Functionality from Untrusted Control Sphere](https://cwe.mitre.org/data/definitions/829.html)
**Affected versions:** `< 0.8.2`
**Patched version:** `0.8.2`
## Summary
The agentmemory CLI (`npx @agentmemory/agentmemory`) auto-installed the iii-engine binary by piping a remote shell script into `sh`:
```ts
execSync("curl -fsSL https://install.iii.dev/iii/main/install.sh | sh")
```
This happened automatically on first run if `iii` was not found in `$PATH`. The script was fetched over HTTPS and executed with the permissions of the user running `npx agentmemory`. No checksum verification, no pinned version, no signature check.
## Impact
If `install.iii.dev` were ever compromised — via DNS hijack, domain takeover, expired certificate + MITM on an untrusted network, BGP attack, or any other supply chain attack — **every new agentmemory user would execute attacker-controlled shell code** as their own user.
This is the canonical "curl | sh" supply chain anti-pattern. It affected:
- Developers running `npx @agentmemory/agentmemory` for the first time
- CI/CD pipelines that installed agentmemory fresh
- Docker builds that installed agentmemory as part of an image
## Patches
Fixed in **0.8.2**:
- Removed `execSync` call entirely from `src/cli.ts`
- CLI now uses an existing local `iii` binary if present in `$PATH`
- Falls back to Docker Compose (`docker compose up -d`) if Docker is available
- Shows manual install instructions if neither iii nor Docker is found:
- `cargo install iii-engine`
- `docker pull iiidev/iii:latest`
- Docs link: https://iii.dev/docs
## Workarounds
Users on affected versions should **install iii-engine manually** and run `agentmemory --no-engine` until upgraded:
```bash
cargo install iii-engine
npx @agentmemory/agentmemory@0.8.1 --no-engine
```
Then upgrade to 0.8.2 at the earliest opportunity.
## References
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
## Credit
@eng-pf
@@ -0,0 +1,62 @@
# GHSA Draft: agentmemory REST and stream services bound to 0.0.0.0 by default
**Severity:** High · **CVSS 3.1:** 8.1 (`AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L`)
**CWE:** [CWE-668 — Exposure of Resource to Wrong Sphere](https://cwe.mitre.org/data/definitions/668.html), [CWE-306 — Missing Authentication for Critical Function](https://cwe.mitre.org/data/definitions/306.html)
**Affected versions:** `< 0.8.2`
**Patched version:** `0.8.2`
## Summary
The default `iii-config.yaml` bound both the REST API (port 3111) and the streams server (port 3112) to `0.0.0.0`, exposing them on every network interface the host could reach. Combined with the fact that `AGENTMEMORY_SECRET` is **unset by default**, this meant any device on the same local network as a running agentmemory instance could read the entire memory store without authentication.
Affected endpoints included:
- `GET /agentmemory/export` — full dump of every captured observation, memory, session, and audit entry
- `GET /agentmemory/sessions` — session list
- `POST /agentmemory/smart-search` — arbitrary search over all captured content
- `POST /agentmemory/observe` — ability to **inject** fake observations
- `POST /agentmemory/remember` — ability to plant arbitrary memories
- All 109 other REST endpoints
## Impact
A developer running agentmemory on a laptop in a coffee shop, office, or conference WiFi effectively published their entire memory store — including captured API keys, file contents, prompts, decisions, and project context — to anyone on the same network.
Attackers on the same network could:
1. **Exfiltrate secrets.** `curl http://<victim-ip>:3111/agentmemory/export` downloads everything. Depending on the incompleteness of the secret redaction (see advisory #06), this could include API keys and tokens.
2. **Inject memories.** An attacker could `POST /agentmemory/observe` or `/remember` with fake observations, poisoning the memory store so future sessions retrieve attacker-controlled context.
3. **Pivot to other services.** The mesh sync endpoint (before the auth fix in advisory #04) accepted peer data from any source.
## Patches
Fixed in **0.8.2**:
- `iii-config.yaml` now binds REST, streams to `127.0.0.1`
- Viewer server already bound to `127.0.0.1`
- New `iii-config.docker.yaml` for Docker deployments: containers bind to `0.0.0.0` internally (required for Docker networking) but host port mapping is restricted to `127.0.0.1:port` in `docker-compose.yml`
- README and API section documentation updated to note 127.0.0.1 as the default
## Workarounds
Users on affected versions should manually edit their `iii-config.yaml` and change the REST and streams `host` values to `127.0.0.1`:
```yaml
modules:
- class: modules::api::RestApiModule
config:
host: 127.0.0.1 # was 0.0.0.0
- class: modules::stream::StreamModule
config:
host: 127.0.0.1 # was 0.0.0.0
```
And set `AGENTMEMORY_SECRET` to a strong random value to protect endpoints even if network exposure is needed.
## References
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
## Credit
@eng-pf
@@ -0,0 +1,47 @@
# GHSA Draft: Unauthenticated mesh sync in agentmemory
**Severity:** High · **CVSS 3.1:** 7.4 (`AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N`)
**CWE:** [CWE-306 — Missing Authentication for Critical Function](https://cwe.mitre.org/data/definitions/306.html), [CWE-862 — Missing Authorization](https://cwe.mitre.org/data/definitions/862.html)
**Affected versions:** `< 0.8.2`
**Patched version:** `0.8.2`
## Summary
agentmemory's mesh federation feature (P2P sync between instances) accepted push/pull requests on its `/agentmemory/mesh/*` endpoints without requiring authentication. The mesh sync function also did not send any `Authorization` header when calling peer instances, meaning the federation protocol was entirely unauthenticated.
## Impact
Any attacker who could reach a mesh-enabled agentmemory instance could:
1. **Push fake memories** via `POST /agentmemory/mesh/receive` — inject attacker-controlled observations, actions, semantic memories, and relations into the target's memory store. This poisons future retrievals and could be used to manipulate what the target's AI agent sees.
2. **Pull the entire memory store** via `GET /agentmemory/mesh/export` — download all memories, actions, and graph data marked as mesh-shareable.
3. **Chain with advisory #03** — combined with the default `0.0.0.0` binding, mesh endpoints were reachable from any device on the local network without any authentication.
Mesh is opt-in (requires an explicit peer registration), so this affected only users who had enabled federation. But those users had no authentication at all.
## Patches
Fixed in **0.8.2**:
- All 5 mesh REST endpoints (`mesh-register`, `mesh-list`, `mesh-sync`, `mesh-receive`, `mesh-export`) now return 503 with `"mesh requires AGENTMEMORY_SECRET"` if the secret is not configured
- The `mem::mesh-sync` function now accepts a `meshAuthToken` parameter and **refuses to sync at all** if the token is missing
- Outgoing push/pull requests include `Authorization: Bearer <secret>` headers
- Server-side, all mesh endpoints check bearer auth via the existing `checkAuth` helper
## Workarounds
Users on affected versions who have mesh federation enabled should:
1. Set `AGENTMEMORY_SECRET` to a strong random value on **both** peers
2. Restart the server
3. Upgrade to 0.8.2 at the earliest opportunity
Users who have **not** enabled mesh federation are not affected by this specific issue, but should still upgrade for the other 5 fixes.
## References
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
## Credit
@eng-pf
@@ -0,0 +1,61 @@
# GHSA Draft: Arbitrary filesystem write via Obsidian export in agentmemory
**Severity:** Medium · **CVSS 3.1:** 6.5 (`AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L`)
**CWE:** [CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')](https://cwe.mitre.org/data/definitions/22.html), [CWE-73 — External Control of File Name or Path](https://cwe.mitre.org/data/definitions/73.html)
**Affected versions:** `< 0.8.2`
**Patched version:** `0.8.2`
## Summary
The `POST /agentmemory/obsidian/export` endpoint accepted a `vaultDir` parameter and passed it directly to `mkdir` and `writeFile` calls without any containment check. A caller could set `vaultDir` to any absolute path on the filesystem and agentmemory would create directories and write Markdown files there with the permissions of the process running the server.
```bash
# Example exploit payload (affected versions only)
curl -X POST http://localhost:3111/agentmemory/obsidian/export \
-H "Content-Type: application/json" \
-d '{"vaultDir": "/etc/cron.d"}'
```
The content written would be agentmemory's exported memories in Markdown format, but an attacker could craft specific memory content beforehand to plant arbitrary files.
## Impact
When chained with advisory #03 (default `0.0.0.0` binding) or advisory #04 (unauthenticated mesh), an attacker on the local network could write arbitrary files to any filesystem location the agentmemory process had write access to.
Possible exploitation paths:
- Write to `~/.ssh/authorized_keys` — SSH key injection
- Write to `/etc/cron.d/*` — cron job injection (if running as root)
- Write to `~/.bashrc` or shell rc files — code execution on next shell
- Overwrite any file the process could write to
## Patches
Fixed in **0.8.2**:
- New `AGENTMEMORY_EXPORT_ROOT` environment variable (default: `~/.agentmemory`)
- `vaultDir` now goes through `resolveVaultDir()` in `src/functions/obsidian-export.ts`:
- Resolves the path with `path.resolve`
- Checks `resolved === root || resolved.startsWith(root + path.sep)`
- Returns `null` if the check fails, and the endpoint returns `{ success: false, error: "vaultDir must be inside AGENTMEMORY_EXPORT_ROOT" }`
- Default export is confined to `~/.agentmemory/vault`
- Tests added in `test/obsidian-export.test.ts` for both the custom-but-valid case and the rejection case
## Known limitations
`resolveVaultDir()` performs lexical containment only — it does not call `fs.realpathSync` / `fs.lstatSync`. A pre-existing symlink under `AGENTMEMORY_EXPORT_ROOT` that points outside the root can still be written through. Users who allow untrusted processes to create files inside `AGENTMEMORY_EXPORT_ROOT` should additionally run agentmemory inside a sandbox that forbids symlink creation, or file a follow-up issue requesting symlink-aware containment.
## Workarounds
Users on affected versions should:
1. **Disable the Obsidian export endpoint** by setting `OBSIDIAN_AUTO_EXPORT=false` (and avoid calling `/agentmemory/obsidian/export` manually)
2. Set `AGENTMEMORY_SECRET` so the endpoint requires bearer auth
3. Upgrade to 0.8.2
## References
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
## Credit
@eng-pf
@@ -0,0 +1,60 @@
# GHSA Draft: Incomplete secret redaction in agentmemory privacy filter
**Severity:** Medium · **CVSS 3.1:** 6.2 (`AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`)
**CWE:** [CWE-532 — Insertion of Sensitive Information into Log File](https://cwe.mitre.org/data/definitions/532.html), [CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor](https://cwe.mitre.org/data/definitions/200.html)
**Affected versions:** `< 0.8.2`
**Patched version:** `0.8.2`
## Summary
agentmemory's privacy filter (`src/functions/privacy.ts`) is supposed to strip API keys, secrets, and bearer tokens from captured observations before they are stored. The filter used regex patterns to detect common token formats. Three modern token formats were missing from the patterns:
1. **Bearer tokens**`Authorization: Bearer <token>` headers were not matched, so any captured HTTP request or response that included an Authorization header flowed into the memory store verbatim.
2. **OpenAI project keys**`sk-proj-*` (the dominant OpenAI API key format since mid-2024) was not matched. The existing `sk-[A-Za-z0-9]{20,}` pattern only caught the legacy format.
3. **GitHub fine-grained service/user tokens**`ghs_*` and `ghu_*` were not matched. The existing `ghp_[A-Za-z0-9]{36}` pattern only caught personal access tokens.
## Impact
agentmemory's README explicitly claimed "Privacy first — API keys, secrets, and `<private>` tags are stripped before anything is stored." That claim was **false** for three common token formats.
Users relying on the privacy filter to protect their captured observations had a false sense of security. Tokens matching these three patterns would:
1. Be captured by `PostToolUse` hooks alongside the rest of the tool output
2. Pass through `stripPrivateData()` unmodified
3. Be LLM-compressed and stored in the memory KV
4. Be exposed to any attacker who could reach the `/agentmemory/export` or `/agentmemory/smart-search` endpoints
5. Be included in Obsidian exports, mesh syncs, and CLAUDE.md bridge writes
When chained with advisory #03 (default `0.0.0.0` binding), this meant network-adjacent attackers could retrieve captured Bearer tokens, OpenAI keys, and GitHub service tokens from the memory store.
## Patches
Fixed in **0.8.2**:
New regex patterns added to `SECRET_PATTERN_SOURCES` in `src/functions/privacy.ts`:
```ts
/Bearer\s+[A-Za-z0-9._\-+/=]{20,}/gi,
/sk-proj-[A-Za-z0-9\-_]{20,}/g,
/(?:sk|pk|rk|ak)-[A-Za-z0-9][A-Za-z0-9\-_]{19,}/g,
/gh[pus]_[A-Za-z0-9]{36,}/g,
```
Three new unit tests in `test/privacy.test.ts` verify each format is now stripped.
## Workarounds
Users on affected versions should:
1. Avoid having agents read files or API responses containing these token formats
2. Use the `<private>` tag around any block containing secrets — that filter was not affected
3. Set `AGENTMEMORY_SECRET` to restrict API access
4. Upgrade to 0.8.2
## References
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
## Credit
@eng-pf
+70
View File
@@ -0,0 +1,70 @@
name: CI
# `paths-ignore` keeps doc-only / website / README / CHANGELOG churn from
# burning runner minutes. Source / config / workflow changes always run.
# `workflow_dispatch` gives a manual re-run button for flake debugging.
on:
push:
branches: [main]
paths-ignore:
- "README.md"
- "CHANGELOG.md"
- "AGENTS.md"
- "ROADMAP.md"
- "website/**"
- "docs/**"
- "assets/**"
- "deploy/**/README.md"
- "**/*.md"
- "**/*.mdx"
pull_request:
branches: [main]
paths-ignore:
- "README.md"
- "CHANGELOG.md"
- "AGENTS.md"
- "ROADMAP.md"
- "website/**"
- "docs/**"
- "assets/**"
- "deploy/**/README.md"
- "**/*.md"
- "**/*.mdx"
workflow_dispatch:
# Cancel in-flight PR runs when a force-push lands. Keep push runs to
# protect against partial state on main.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
# Don't bail the whole matrix on one cell's failure — we want to
# see whether the same failure reproduces across OSes (e.g.
# whether a flake is platform-specific or universal).
fail-fast: false
matrix:
# Windows held back: test/obsidian-export.test.ts has hardcoded
# POSIX paths (`/tmp/...`) that fail on D:\ drive runners.
# src/functions/obsidian-export.ts needs os.tmpdir() + path.join
# rework before Windows can be added back. Tracked as follow-up.
os: [ubuntu-latest, macos-latest]
node-version: [20, 22]
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
# Two-step install: generate a lockfile in-runner with
# --package-lock-only, then install from it with `npm ci`.
# Lockfiles are gitignored at the repo level.
- run: npm install --package-lock-only --legacy-peer-deps --no-audit --no-fund
- run: npm ci --legacy-peer-deps --no-audit --no-fund
- run: npm run build
- run: npm run skills:check
- run: npm test
+124
View File
@@ -0,0 +1,124 @@
name: Publish to npm
on:
release:
types: [published]
workflow_dispatch:
inputs:
packages:
description: "Packages to publish (comma-separated: agentmemory,mcp,fs-watcher)"
required: false
default: "agentmemory,mcp,fs-watcher"
# Workflow-level permissions stay minimal — only `contents: read`
# is required to check out the repo. `id-token: write` is granted on
# the publish job for npm's --provenance Sigstore OIDC mint.
permissions:
contents: read
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v6
with:
# Don't persist the GITHUB_TOKEN to .git/config — the
# publish steps don't push back to the repo, so the token
# only needs to live in memory for this checkout.
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: 22
registry-url: https://registry.npmjs.org
# Two-step install: generate a lockfile in-runner with
# --package-lock-only, then install from it with `npm ci`. Gives a
# single deterministic dep graph across build / test / publish
# within one job — important because publish uses `--provenance`.
# Lockfiles are gitignored at the repo level.
- run: npm install --package-lock-only --legacy-peer-deps --no-audit --no-fund
- run: npm ci --legacy-peer-deps --no-audit --no-fund
- run: npm run build
- run: npm test
- name: Publish @agentmemory/agentmemory
run: |
if npm view "@agentmemory/agentmemory@$(node -p "require('./package.json').version")" version >/dev/null 2>&1; then
echo "Version already published, skipping"
else
npm publish --provenance --access public
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Wait for npm registry propagation
run: |
VERSION=$(node -p "require('./package.json').version")
for i in $(seq 1 24); do
if npm view "@agentmemory/agentmemory@$VERSION" version >/dev/null 2>&1; then
echo "Registry propagated after ${i} attempt(s)"
exit 0
fi
echo "Attempt $i: not yet available, sleeping 5s..."
sleep 5
done
echo "ERROR: registry never propagated after 2 minutes" >&2
exit 1
- name: Publish @agentmemory/mcp shim
working-directory: packages/mcp
run: |
SHIM_VERSION=$(node -p "require('./package.json').version")
if npm view "@agentmemory/mcp@$SHIM_VERSION" version >/dev/null 2>&1; then
echo "Shim version already published, skipping"
else
npm publish --provenance --access public
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Wait for @agentmemory/mcp registry propagation
working-directory: packages/mcp
run: |
SHIM_VERSION=$(node -p "require('./package.json').version")
for i in $(seq 1 24); do
if npm view "@agentmemory/mcp@$SHIM_VERSION" version >/dev/null 2>&1; then
echo "Shim propagated after ${i} attempt(s)"
exit 0
fi
echo "Attempt $i: not yet available, sleeping 5s..."
sleep 5
done
echo "ERROR: shim never propagated after 2 minutes" >&2
exit 1
- name: Publish @agentmemory/fs-watcher connector
working-directory: integrations/filesystem-watcher
run: |
FSW_VERSION=$(node -p "require('./package.json').version")
if npm view "@agentmemory/fs-watcher@$FSW_VERSION" version >/dev/null 2>&1; then
echo "fs-watcher version already published, skipping"
else
npm publish --provenance --access public
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Wait for @agentmemory/fs-watcher registry propagation
working-directory: integrations/filesystem-watcher
run: |
FSW_VERSION=$(node -p "require('./package.json').version")
for i in $(seq 1 24); do
if npm view "@agentmemory/fs-watcher@$FSW_VERSION" version >/dev/null 2>&1; then
echo "fs-watcher propagated after ${i} attempt(s)"
exit 0
fi
echo "Attempt $i: not yet available, sleeping 5s..."
sleep 5
done
echo "ERROR: fs-watcher never propagated after 2 minutes" >&2
exit 1