@jacebenson/jsn 3.1.0 → 3.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacebenson/jsn",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
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": {
@@ -27,6 +27,7 @@
27
27
  "node": ">=18.0.0"
28
28
  },
29
29
  "dependencies": {
30
+ "@inquirer/core": "^10.1.0",
30
31
  "@inquirer/prompts": "^7.5.1",
31
32
  "chalk": "^5.4.1",
32
33
  "cli-table3": "^0.6.5",
@@ -34,7 +35,7 @@
34
35
  },
35
36
  "devDependencies": {
36
37
  "@eslint/js": "^10.0.1",
37
- "@inquirer/search": "^4.2.0",
38
+ "@inquirer/search": "^4.2.1",
38
39
  "globals": "^17.6.0"
39
40
  },
40
41
  "files": [
@@ -12,151 +12,76 @@ compatibility: |
12
12
  Requires jsn CLI (github.com/jacebenson/jsn). Install via:
13
13
  npm install -g @jacebenson/jsn
14
14
  Works with Claude Code, OpenCode, Cursor, and agentskills-compatible tools.
15
-
16
- Windows users: Install Node.js first, then the npm command above. If jsn is not
17
- in your PATH, the setup command will automatically detect its location and show
18
- the correct command path.
19
15
  metadata:
20
16
  author: jacebenson
21
- version: "1.1.0"
17
+ version: "3.1.1"
22
18
  repository: https://github.com/jacebenson/jsn
23
19
  ---
24
20
 
25
- # Jace's ServiceNow CLI
21
+ # Jace's ServiceNow CLI (jsn)
26
22
 
27
- Explore and manage ServiceNow instances. Works standalone or with AI agents.
23
+ Explore and manage ServiceNow instances. Interactive paginated pickers with server-side search on all list commands.
28
24
 
29
25
  ## Discovery
30
26
 
31
- Commands are self-documenting. Use these to learn what's available:
32
-
33
27
  ```bash
34
- jsn --help # Root help with all top-level commands (grouped by category)
35
- jsn <command> --help # Detailed usage, flags, and examples for any command
28
+ jsn --help # All commands grouped by domain
29
+ jsn <command> --help # Flags, subcommands, and examples
36
30
  ```
37
31
 
32
+ ## Interactive Picker
33
+
34
+ All `list` subcommands use a paginated interactive picker in TTY mode:
35
+ - Arrow through items (10 per page)
36
+ - Type to search (server-side LIKE query)
37
+ - Scroll past last loaded item to load next page
38
+ - Enter to select, Esc to cancel
39
+ - Falls back to table output with `--json`
40
+
38
41
  ## Agent Rules
39
42
 
40
- 1. **Output modes** — `--json` when parsing data; `--md` when presenting to humans; `--agent` for automation
43
+ 1. **Output modes** — `--json` when parsing data; text when presenting to humans
41
44
  2. **Use sys_id for updates** — All update/delete operations require sys_id
42
45
  3. **Check auth first** — Run `jsn auth status` before operations
43
46
  4. **NEVER logout** — Only run `jsn auth logout` if the user explicitly asks
44
47
  5. **Use `--profile <name>`** to target a specific instance, or `jsn profiles use <name>` to change default
45
- 6. **Before using `eval` or `rest`** — Ask yourself: *"Have I checked if there's a more specific jsn command?"* Verify `jsn records --table <name> create` won't work first. Prefer specific over generic over escape hatch over eval.
46
- 7. **CONFIRM before destructive operations** — Always show the user exactly what will be created, updated, or deleted and ask for explicit confirmation before executing. Never run `create`, `update`, `delete`, `set`, or `remove` commands without user approval.
47
-
48
- ## ⚠️ Destructive Operations Require Confirmation
49
-
50
- **jsn does not have a `--confirm` or `--dry-run` flag.** It assumes you mean what you type. This means **YOU** (the agent) are the safety layer.
51
-
52
- **Before any write operation, you MUST:**
53
-
54
- 1. **Show the user what you found** — Run a `list` or `show` command first
55
- 2. **Present the exact command you plan to run** — Include the sys_id, table name, and data
56
- 3. **Wait for explicit approval** — "Proceed? [y/N]" or similar
57
-
58
- **Examples of destructive commands that require confirmation:**
59
- - `jsn records --table <name> create`
60
- - `jsn records --table <name> update <sys_id>`
61
- - `jsn records --table <name> delete <sys_id>`
62
- - `jsn updatesets set <name>`
63
- - `jsn profiles remove <name>`
64
- - Any `delete`, `update`, `create`, `set`, or `remove` subcommand
65
-
66
- **Good pattern:**
67
- ```
68
- User: "Delete that incident"
69
- Agent: "Found: INC0010001 'Server down' (sys_id: abc123...)
70
- Command: jsn records --table incident delete abc123...
71
- Proceed? [y/N]"
72
- User: "y"
73
- Agent: [runs command]
74
- ```
75
-
76
- **Bad pattern:**
77
- ```
78
- User: "Delete that incident"
79
- Agent: [immediately runs jsn records --table incident delete ...]
80
- ```
81
-
82
- ## ⚠️ AVOID `jsn eval` for Record Creation
83
-
84
- **Why:** `jsn eval` runs server-side JavaScript in the global scope. It returns HTTP 200 even when:
85
- - The insert fails due to ACL violations
86
- - Mandatory fields are missing
87
- - The record lands in the wrong scope
88
- - Logic errors prevent the insert entirely
89
-
90
- **The AI trap:** Agents see "success" and assume the record was created. It wasn't.
91
-
92
- **Always use instead:** `jsn records --table <name> create` — it returns the created record with sys_id or an explicit validation error.
93
-
94
- **Only use `eval` when:** No specific command exists, `records` lacks required fields, and `rest` doesn't work. This is rare.
48
+ 6. **Before using `eval` or `rest`** — Ask: *"Is there a more specific jsn command?"* Prefer specific over generic over escape hatch over eval.
49
+ 7. **CONFIRM before destructive operations** — Show what will be created/updated/deleted and ask for approval.
95
50
 
96
51
  ## Command Hierarchy
97
52
 
98
53
  Pick the most specific tool for the job. **Never default to eval** — it's the last resort:
99
54
 
100
- 1. **Specific commands** — `jsn flows`, `jsn rules`, `jsn jobs`, etc. — curated views with domain-aware formatting and validation
101
- 2. **`jsn records --table <name>`** — generic CRUD on any table (the workhorse, preferred for record creation)
102
- 3. **`jsn rest`** — raw Table API escape hatch when records command lacks required fields
103
- 4. **`jsn eval`** — ⚠️ **LAST RESORT ONLY** — server-side script execution when no other option exists
104
- 5. **Ask the human** — if none of the above work. Never generate standalone GlideRecord scripts as a fallback.
105
-
106
- ## JSON Envelope
107
-
108
- All commands support `--json`. The envelope structure:
109
-
110
- ```json
111
- {
112
- "ok": true,
113
- "data": [ ... ],
114
- "summary": "5 records",
115
- "breadcrumbs": [
116
- {"action": "show", "cmd": "jsn records --table incident <sys_id>", "description": "View details"}
117
- ]
118
- }
119
- ```
120
-
121
- Breadcrumbs suggest next commands — follow them for navigation.
55
+ 1. **Specific commands** — `jsn flows`, `jsn rules`, `jsn catalogitems`, etc.
56
+ 2. **`jsn records --table <name>`** — generic CRUD on any table
57
+ 3. **`jsn rest`** — raw Table API escape hatch
58
+ 4. **`jsn eval`** — ⚠️ **LAST RESORT ONLY**
59
+ 5. **Ask the human** — if none of the above work
60
+
61
+ ## Key Commands
62
+
63
+ | Domain | Commands |
64
+ |--------|---------|
65
+ | **Core** | `incidents`, `changes`, `requests`, `tasks` |
66
+ | **Catalog** | `catalogitems list/show/create` — items with variables and flow info |
67
+ | **Automation** | `flows`, `actions`, `rules`, `workflows`, `triggers`, `scheduledjobs` |
68
+ | **Access** | `acls`, `b4rules`, `roles`, `groups`, `users` |
69
+ | **UX** | `forms` (section/element layout), `lists`, `clientscripts`, `uipolicies` |
70
+ | **Data** | `tables`, `columns`, `includes`, `logs`, `properties`, `records` |
71
+ | **Config** | `setup`, `auth`, `profiles`, `updatesets`, `scopes` |
72
+ | **Developer** | `eval`, `rest`, `skill`, `version` |
122
73
 
123
74
  ## Troubleshooting Field Behavior
124
75
 
125
- When a user asks about field behavior (why a picker won't show inactive users, why a field is read-only, why a reference qualifier behaves unexpectedly), do NOT just check dictionary records or ACLs. Field behavior is often controlled by **before-query business rules**.
126
-
127
- **Check order (priority):**
128
-
129
- 1. **Before-query business rules** — `sys_script` with `when=before`, `action=query`, matching `collection` (table)
130
- ```bash
131
- jsn records list --table sys_script --query "collection=sys_user^when=before^action=query^active=true" --json
132
- ```
133
- A common case: inactive user filters on `sys_user` are implemented as a before-query BR that adds `active=true` to the query condition.
134
-
135
- 2. **ACLs** — `sys_security_acl` — read/write/delete permissions on tables and fields
136
- ```bash
137
- jsn acls list --query "name=incident" --json
138
- ```
76
+ Check order (priority):
139
77
 
140
- 3. **Dictionary overrides** — `sys_dictionary` — reference qualifiers, field attributes, default values
78
+ 1. **Before-query business rules** — `sys_script` with `when=before`, `action=query`
141
79
  ```bash
142
- jsn records list --table sys_dictionary --query "name=incident^element=caller_id" --json
80
+ jsn b4rules list --query "collection=sys_user"
143
81
  ```
144
-
145
- 4. **Client scripts** — `sys_script_client` — UI-side visibility, read-only, or value-change logic
146
- ```bash
147
- jsn records list --table sys_script_client --query "table=incident^active=true" --json
148
- ```
149
-
150
- 5. **UI policies** — `sys_ui_policy` — form-level field behavior (mandatory, read-only, visible)
151
- ```bash
152
- jsn records list --table sys_ui_policy --query "table=incident^active=true" --json
153
- ```
154
-
155
- **Example:** "Why can't I pick an inactive user on the incident form?"
156
- - First guess: Dictionary reference qualifier on `caller_id`? → Check `sys_dictionary`
157
- - Most likely: Before-query BR on `sys_user` that filters `active=true` → Check `sys_script` first
158
-
159
- **Rule of thumb:** If a picker is silently filtering results (no error, just fewer options), it's a before-query BR. If it shows an error, it's an ACL or dictionary constraint.
82
+ 2. **ACLs** — `jsn acls list --query "name=incident"`
83
+ 3. **Dictionary overrides** — `jsn records list --table sys_dictionary --query "name=incident^element=caller_id"`
84
+ 4. **Client scripts** / **UI policies** — form-level field behavior
160
85
 
161
86
  ## Configuration
162
87
 
@@ -164,11 +89,4 @@ When a user asks about field behavior (why a picker won't show inactive users, w
164
89
  ~/.config/servicenow/
165
90
  ├── config.json # Profiles and settings
166
91
  └── credentials.json # Auth tokens (fallback)
167
-
168
- .servicenow/ # Per-repo config (optional)
169
- └── config.json # Project-specific settings
170
92
  ```
171
-
172
- **Environment variables:**
173
- - `SERVICENOW_TOKEN` — Override stored token
174
- - `SERVICENOW_INSTANCE` — Override instance URL