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
42 changes: 42 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: Bug report
about: Something isn't working
title: "[Bug] "
labels: bug
---

## What happened

<!-- A clear description of the bug. -->

## Reproduction

<!-- The minimum command(s) that trigger the bug. Copy-paste-runnable is ideal. -->

```bash
smcp <command> [args...]
```

## What you expected

<!-- What should have happened instead. -->

## What actually happened

<!-- The actual output, error message, or behavior. Include the full stack trace if it threw. -->

```
<paste output here>
```

## Environment

- `smcp` version: <!-- output of `smcp version` or `smcp --help` first line -->
- Gateway URL / version: <!-- e.g. `http://localhost:8000`, gateway commit/tag if known -->
- Node version: <!-- output of `node --version` -->
- OS: <!-- macOS / Linux / Windows -->
- Install method: <!-- `npm i -g @datacline/smcp`, `npx`, or local checkout -->

## Anything else?

<!-- Logs, screenshots, related issues, attempts you've made. -->
31 changes: 31 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: Feature request
about: Suggest an addition or change to the CLI
title: "[Feature] "
labels: enhancement
---

## Use case

<!-- The problem you're trying to solve. Tell us the *why* before the *what*. -->

## Current workaround

<!-- What do you do today without this feature? "Nothing, I'm blocked" is a valid answer. -->

## Proposed command / flag

<!-- A rough sketch of the CLI surface you'd want. -->

```bash
smcp <group> <subcommand> --flag value
```

## Why in the CLI and not your own script

<!-- The CLI surface is intentionally small. Tell us what makes this generally useful
(vs. a one-off you can build on top of `curl` against the gateway HTTP API). -->

## Alternatives considered

<!-- Any other approaches you've thought about and why you discarded them. -->
27 changes: 27 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Summary

<!-- 1-3 lines. What this PR changes and why. Reference any related issue: `Fixes #123`. -->

## Changes

<!-- Bullet list of meaningful changes. -->

-

## Test plan

- [ ] `npm run lint --workspace @datacline/smcp` clean
- [ ] `npm run build --workspace @datacline/smcp` clean (ESM + CJS in `dist/`)
- [ ] `npm test --workspace @datacline/smcp` passes
- [ ] `npm pack --dry-run --workspace @datacline/smcp` shows expected files only
- [ ] Manually exercised affected `smcp` commands against a running gateway
- [ ] Added regression test that fails on main and passes with this change (if fixing a bug)

## Breaking changes?

<!-- Yes / no. If yes, what breaks and how should consumers migrate? Bump the major and update CHANGELOG.md. -->

## Gateway / policy-engine changes?

<!-- The CLI is paired with `server-java/` (gateway) and `policy-engine-go/`.
If this PR depends on changes in those services, link them. -->
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
groups:
development:
dependency-type: dev
patterns:
- '*'
open-pull-requests-limit: 5

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
73 changes: 73 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: ci

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
test:
name: node ${{ matrix.node }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: ['18.17', '20', '22']
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm

- run: npm ci --workspace @datacline/smcp --include-workspace-root

- run: npm run lint --workspace @datacline/smcp

- run: npm run build --workspace @datacline/smcp

- run: npm test --workspace @datacline/smcp

pack-check:
name: verify package contents
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm

- run: npm ci --workspace @datacline/smcp --include-workspace-root

- run: npm run build --workspace @datacline/smcp

- name: Inspect tarball
run: |
npm pack --dry-run --json --workspace @datacline/smcp > pack.json
node -e "
const p = JSON.parse(require('fs').readFileSync('pack.json'));
const files = p[0].files.map(f => f.path).sort();
const required = ['dist/smcp.cjs', 'dist/smcp.mjs', 'README.md', 'CHANGELOG.md', 'LICENSE', 'package.json'];
const missing = required.filter(r => !files.includes(r));
if (missing.length) {
console.error('Missing required files in tarball:', missing);
console.error('Got:', files);
process.exit(1);
}
const forbidden = files.filter(f => f.startsWith('bin/') || f.startsWith('src/') || f.startsWith('test/') || f === 'tsconfig.json' || f === 'tsup.config.ts');
if (forbidden.length) {
console.error('Tarball contains files that should not be published:', forbidden);
process.exit(1);
}
console.log('Tarball OK. Files:', files);
"
53 changes: 0 additions & 53 deletions .github/workflows/cli-publish.yml

This file was deleted.

92 changes: 92 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: release

on:
push:
tags:
- 'v*'

permissions:
contents: write
id-token: write

concurrency:
group: release
cancel-in-progress: false

jobs:
publish:
name: publish to npm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: https://registry.npmjs.org
cache: npm

- run: npm ci --workspace @datacline/smcp --include-workspace-root

- run: npm run lint --workspace @datacline/smcp

- run: npm run build --workspace @datacline/smcp

- run: npm test --workspace @datacline/smcp

- name: Verify tag matches package.json version
run: |
TAG="${{ github.ref }}"
TAG="${TAG#refs/tags/}"
VERSION=$(node -e "console.log(require('./packages/smcp/package.json').version)")
if [ "$TAG" != "v$VERSION" ]; then
echo "Error: tag '$TAG' does not match package.json version 'v$VERSION'"
exit 1
fi
echo "✓ Tag version matches package.json"

- name: Verify package contents
run: |
npm pack --dry-run --json --workspace @datacline/smcp > pack.json
node -e "
const p = JSON.parse(require('fs').readFileSync('pack.json'));
const files = p[0].files.map(f => f.path).sort();
const required = ['dist/smcp.cjs', 'dist/smcp.mjs', 'README.md', 'CHANGELOG.md', 'LICENSE', 'package.json'];
const missing = required.filter(r => !files.includes(r));
if (missing.length) {
console.error('Missing required files in tarball:', missing);
console.error('Got:', files);
process.exit(1);
}
const forbidden = files.filter(f => f.startsWith('bin/') || f.startsWith('src/') || f.startsWith('test/') || f === 'tsconfig.json' || f === 'tsup.config.ts');
if (forbidden.length) {
console.error('Tarball contains files that should not be published:', forbidden);
process.exit(1);
}
console.log('Tarball OK. Files:', files);
"

- name: Determine npm dist-tag from version
id: dist_tag
run: |
VERSION=$(node -e "console.log(require('./packages/smcp/package.json').version)")
# Detect prerelease (anything with a hyphen: 1.0.0-alpha.1, 1.0.0-beta.2, ...)
if [[ "$VERSION" == *-* ]]; then
# Use the prerelease label as the dist-tag (alpha/beta/rc/next)
TAG=$(echo "$VERSION" | sed -E 's/.*-([a-zA-Z]+)\..*/\1/')
[ -z "$TAG" ] && TAG=next
else
TAG=latest
fi
echo "Resolved dist-tag: $TAG (from version $VERSION)"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"

- name: Publish to npm
run: npm publish --workspace @datacline/smcp --access public --provenance --tag "${{ steps.dist_tag.outputs.tag }}"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Create GitHub Release
run: gh release create "${{ github.ref }}" --generate-notes
env:
GH_TOKEN: ${{ github.token }}
Loading
Loading