@jacebenson/jsn 4.3.5-dev.9 → 4.3.6-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jace Benson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -193,7 +193,7 @@ npm install
193
193
  npm test
194
194
  ```
195
195
 
196
- Releases are manual. After changes land on `main`, run `npm run release -- patch` (or `minor`, `major`) to test, bump the version, and push the commit and tag. When ready, publish to npm with `npm publish --access public`. Git tags mark releases; GitHub Release entries are not required.
196
+ Releases run from the GitHub Actions workflow. Dispatch `Release production` with `patch`, `minor`, or `major`. The workflow tests and lints the repo, bumps the version, pushes the commit and tag, dispatches the npm publish workflow, and creates the GitHub release.
197
197
 
198
198
  ## License
199
199
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacebenson/jsn",
3
- "version": "4.3.5-dev.9",
3
+ "version": "4.3.6-dev.10",
4
4
  "description": "A command-line interface for ServiceNow that follows the Unix philosophy: simple, composable, and scriptable.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,9 +12,7 @@
12
12
  "lint": "npx eslint src/ bin/ test/",
13
13
  "start": "node bin/jsn.js",
14
14
  "docs": "npm --prefix docs run build",
15
- "docs:serve": "npm --prefix docs run serve",
16
- "tag-reminder": "node scripts/tag-reminder.js",
17
- "release": "node scripts/release.js"
15
+ "docs:serve": "npm --prefix docs run serve"
18
16
  },
19
17
  "keywords": [
20
18
  "servicenow",
@@ -43,7 +41,6 @@
43
41
  "bin/jsn.js",
44
42
  "src/",
45
43
  "skills/",
46
- "scripts/",
47
44
  "README.md",
48
45
  "LICENSE"
49
46
  ]
@@ -14,7 +14,7 @@ compatibility: |
14
14
  Works with Claude Code, OpenCode, Cursor, and agentskills-compatible tools.
15
15
  metadata:
16
16
  author: jacebenson
17
- version: "4.0.0"
17
+ version: "4.3.6"
18
18
  repository: https://github.com/jacebenson/jsn
19
19
  ---
20
20
 
@@ -65,7 +65,7 @@ Pick the most specific tool for the job. **Never default to eval** — it's the
65
65
  |--------|---------|
66
66
  | **Core** | `incidents`, `changes`, `requests`, `tasks` |
67
67
  | **Catalog** | `catalogitems list/show/create` — items with variables and flow info |
68
- | **Automation** | `flows`, `actions`, `rules`, `workflows`, `triggers`, `scheduledjobs` |
68
+ | **Automation** | `flows`, `actions`, `rules`, `triggers`, `scheduledjobs` |
69
69
  | **Access** | `acls`, `b4rules`, `roles`, `groups`, `users` |
70
70
  | **UX** | `forms` (section/element layout), `lists`, `clientscripts`, `uipolicies` |
71
71
  | **Data** | `tables`, `columns`, `includes`, `logs`, `properties`, `records` |
@@ -73,16 +73,16 @@ Pick the most specific tool for the job. **Never default to eval** — it's the
73
73
  | **Docs** | `docs sync`, `docs status`, `docs search`, `docs serve` |
74
74
  | **Developer** | `eval`, `rest`, `skill`, `version` |
75
75
 
76
- ### `jsn rest` examples
76
+ ### Table and raw REST examples
77
77
 
78
78
  ```bash
79
- # Query any table by name
80
- jsn rest --table incident --query "active=true" --limit 5 --json
79
+ # Query a table with the normal records command
80
+ jsn records list --table incident --query "active=true" --limit 5 --json
81
81
 
82
- # GET a single record
83
- jsn rest --table incident --sys-id abc123... --json
82
+ # Get a single record
83
+ jsn records get --table incident --sys-id abc123... --json
84
84
 
85
- # Raw endpoint access
85
+ # Raw endpoint access when no specific command fits
86
86
  jsn rest "/api/now/table/incident?sysparm_limit=3" --json
87
87
  ```
88
88
 
@@ -106,8 +106,6 @@ jsn docs search "REST API" --bundle it-service-management --json
106
106
  # Start the web UI
107
107
  jsn docs serve
108
108
 
109
- # Share on your network
110
- jsn docs serve --expose
111
109
  ```
112
110
 
113
111
  **Re-running `jsn docs sync`** does a smart incremental refresh — pulls latest docs and only rebuilds changed files (seconds, not minutes).
@@ -129,5 +127,5 @@ Check order (priority):
129
127
  ```
130
128
  ~/.config/servicenow/
131
129
  ├── config.json # Profiles and settings
132
- └── credentials.json # Auth tokens (fallback)
130
+ └── credentials/ # Auth tokens (fallback, one file per key)
133
131
  ```
@@ -68,7 +68,6 @@ export async function enrichCatalogItem({ sdk, instanceUrl, sysID }) {
68
68
  flowCmd = `jsn flows show ${flowVal.value}`;
69
69
  }
70
70
  const wfName = getStringField(item, 'workflow') || '';
71
- const wfID = item.workflow?.value || '';
72
71
  const planName = getStringField(item, 'delivery_plan') || getStringField(item, 'execution_plan') || '';
73
72
 
74
73
  const data = {
@@ -80,7 +79,7 @@ export async function enrichCatalogItem({ sdk, instanceUrl, sysID }) {
80
79
  flow: flowName || undefined,
81
80
  flow_cmd: flowCmd || undefined,
82
81
  workflow: wfName || undefined,
83
- workflow_cmd: (wfName && wfID) ? `jsn workflows show ${wfID}` : undefined,
82
+
84
83
  execution_plan: planName || undefined,
85
84
  variables: totalVars > 0 ? {
86
85
  count: totalVars,
@@ -117,7 +116,6 @@ export function buildCatalogFormatted(data, standalone, setVars, totalVars) {
117
116
  if (data.workflow) {
118
117
  lines.push('─ Workflow ─');
119
118
  lines.push(` ${data.workflow}`);
120
- if (data.workflow_cmd) lines.push(` → ${data.workflow_cmd}`);
121
119
  lines.push('');
122
120
  }
123
121
  if (totalVars > 0) {
@@ -1,61 +0,0 @@
1
- #!/bin/bash
2
- # pre-commit-check.sh - Run this before committing to check architecture compliance
3
-
4
- echo "🔍 Checking architecture patterns..."
5
-
6
- # Check for forbidden SDK patterns
7
- FORBIDDEN_PATTERNS=(
8
- "func.*Client.*ListForm"
9
- "func.*Client.*ListList"
10
- "func.*Client.*GetSP"
11
- "func.*Client.*ListSP"
12
- )
13
-
14
- ERRORS=0
15
-
16
- for pattern in "${FORBIDDEN_PATTERNS[@]}"; do
17
- matches=$(grep -r "$pattern" internal/sdk/*.go 2>/dev/null | grep -v "_test.go" | grep -v "^Binary")
18
- if [ ! -z "$matches" ]; then
19
- echo "❌ Found forbidden SDK pattern: $pattern"
20
- echo "$matches"
21
- ERRORS=$((ERRORS + 1))
22
- fi
23
- done
24
-
25
- # Check that commands don't import old SDK types
26
- BAD_IMPORTS=(
27
- "sdk.FormSection"
28
- "sdk.FormElement"
29
- "sdk.ListLayout"
30
- "sdk.ListElement"
31
- "sdk.SPPage"
32
- "sdk.SPWidgetInstance"
33
- )
34
-
35
- for pattern in "${BAD_IMPORTS[@]}"; do
36
- matches=$(grep -r "$pattern" internal/commands/**/*.go 2>/dev/null)
37
- if [ ! -z "$matches" ]; then
38
- echo "❌ Command using SDK type instead of local type: $pattern"
39
- echo "$matches"
40
- ERRORS=$((ERRORS + 1))
41
- fi
42
- done
43
-
44
- # Run architecture tests
45
- echo "🧪 Running architecture tests..."
46
- if ! go test ./internal/sdk -run TestNoSDKHelperMethods -run TestCommandsUseDirectSDKList > /dev/null 2>&1; then
47
- echo "❌ Architecture tests failed"
48
- go test ./internal/sdk -v -run "TestNoSDKHelperMethods|TestCommandsUseDirectSDKList"
49
- ERRORS=$((ERRORS + 1))
50
- fi
51
-
52
- if [ $ERRORS -eq 0 ]; then
53
- echo "✅ All architecture checks passed!"
54
- exit 0
55
- else
56
- echo ""
57
- echo "⚠️ Architecture violations found!"
58
- echo " Remember: Commands should call app.SDK.List() directly with local types."
59
- echo " See internal/commands/forms.go for the correct pattern."
60
- exit 1
61
- fi
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env node
2
- import { execSync } from 'child_process';
3
- import { readFileSync } from 'fs';
4
- import { fileURLToPath } from 'url';
5
- import { dirname, join } from 'path';
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
9
-
10
- const type = process.argv[2];
11
- if (!type || !['patch', 'minor', 'major'].includes(type)) {
12
- console.error('Usage: npm run release -- <patch|minor|major>');
13
- process.exit(1);
14
- }
15
-
16
- let branch;
17
- try {
18
- branch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
19
- } catch {
20
- console.error('Error: Not in a git repository');
21
- process.exit(1);
22
- }
23
-
24
- if (branch !== 'main') {
25
- console.error(`Error: Releases can only be made from 'main' branch (currently on '${branch}')`);
26
- process.exit(1);
27
- }
28
-
29
- const prefix = 'v';
30
-
31
- console.log('');
32
- console.log(`🚀 Releasing from '${branch}'`);
33
- console.log(` Bump: ${type}`);
34
- console.log('');
35
-
36
- // Run tests
37
- console.log('⏳ Running tests...');
38
- try {
39
- execSync('npm test', { stdio: 'inherit' });
40
- } catch {
41
- console.error('');
42
- console.error('❌ Tests failed. Release aborted.');
43
- process.exit(1);
44
- }
45
-
46
- // Bump version with correct tag prefix
47
- console.log('');
48
- console.log(`⏳ Bumping version (${type})...`);
49
- execSync(`npm version ${type} --tag-version-prefix=${prefix}`, { stdio: 'inherit' });
50
-
51
- // Push commits and tags
52
- console.log('');
53
- console.log('⏳ Pushing to origin...');
54
- execSync('git push && git push --tags', { stdio: 'inherit' });
55
-
56
- // Show final state
57
- const newPkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
58
- console.log('');
59
- console.log('✅ Release complete!');
60
- console.log(` Version: ${newPkg.version}`);
61
- console.log(` Tag: ${prefix}${newPkg.version}`);
62
- console.log('');
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- import { execSync } from 'child_process';
3
- import { readFileSync } from 'fs';
4
- import { fileURLToPath } from 'url';
5
- import { dirname, join } from 'path';
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
9
-
10
- let branch;
11
- try {
12
- branch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
13
- } catch {
14
- branch = 'unknown';
15
- }
16
-
17
- const version = pkg.version;
18
- const prefix = 'v';
19
-
20
- console.log('');
21
- console.log('📦 Release Reminder');
22
- console.log('');
23
- console.log(` Current version: ${version}`);
24
- console.log(` Current branch: ${branch}`);
25
- console.log('');
26
- console.log(' To create a release tag, run:');
27
- console.log('');
28
- console.log(` git tag ${prefix}${version}`);
29
- console.log(' git push origin --tags');
30
- console.log('');