Repository navigation
Conversation
- role get: look up by --id or --name via GET /roles?q=roleId==/roleName==
(no /roles/{id} endpoint exists); --privileges adds expand=privileges
- Role.Privileges is now []RolePrivilege (API returns objects)
- role get: interactive role picker when --id/--name omitted, optional
"Display role privileges? [y/Q]" prompt in table output, privileges
sorted by service and name, status color-coded, CSV output support
- role create: --name/--description/--privilege (names or IDs resolved
to IDs) and --from-file using the API request shape
- replace role update (non-existent endpoint) with add-privileges and
remove-privileges (PUT /roles/{id|name/<name>}/add|removePrivileges)
- role delete: support --name
- docs, README, completions; bug record in docs/issues/pending
- role edit: TUI to add/remove privileges, grouped by service, then by object with one column per action (view/create/update/delete/execute/ changeperm); non-matching names listed under Other; review step with add-before-remove apply and a guard against removing all privileges - role add-privileges / remove-privileges open the editor in add-only / remove-only mode when --privilege is omitted on a terminal - role create: interactive wizard (name, description, optional clone source, editor) and non-interactive --from-role <name|id> - role picker is now a filterable huh select - client: GroupPrivileges, DiffPrivileges, FindRole with tests; internal/tui/privmatrix Bubble Tea model with tests - deps: charmbracelet/huh, bubbletea, bubbles - docs: role.md editor/edit/--from-role, README, docs/CLAUDE.md deps, completions; CR-0040 moved to pending
- internal/tui/prompt.go: Prompter with Text, Secret, Select, MultiSelect, Confirm, Timezone and generic PickOne; huh forms on a terminal (arrows, / filter, checkboxes with defaults pre-checked), line-based fallback with the historical input format when stdin/stderr is not a terminal; one shared buffered reader so piped answers are not lost between prompts; IICS_ACCESSIBLE=1 enables huh accessible mode - cmd/user_prompt.go: promptText/Password/Select/MultiSelect/YesNo and promptTimezone delegate to the Prompter (signatures unchanged); promptUserSearch uses the shared helpers - cmd/role_prompt.go: pickRole uses tui.PickOne - tests for the line-based path, including sequential piped prompts - docs: interactive.md (keys, accessible mode, piped format), links from user/group/environment/agent/role docs, IICS_ACCESSIBLE in README; CR-0041 updated for the line-based fallback decision
- internal/tui/userwizard.go: huh form with Identity, Single sign-on (SSO only), Details and Membership pages; user name suggestion, required-field and email validation, filterable group and role checklists pre-checked with current membership, time zone select on update; review step (create summary / update diff) with apply, back to editing, or cancel; create requires at least one group or role - update shows user name, authentication and state read-only instead of prompting for values the update API ignores - client: aliasName on create (documented as required for SSO) - cmd/user.go: runUserWizard delegates to tui.RunUserWizard; cancel prints "Canceled." instead of failing - tests for change/summary builders, user name suggestion, email check - docs: user.md wizard section; CR-0041 progress; new bug record for the existing V2 user update failure (403 REPO_10704)
- internal/tui/review.go: shared confirmReview (apply / back / cancel, apply hidden when nothing to apply), SetChanges (+/- lines), requiredUnique and atLeastOne validators; user wizard reuses them - internal/tui/groupwizard.go: create asks name (duplicates rejected), description and roles (filterable checklist, at least one); update shows name/description read-only, roles pre-checked, review of +/- role changes, no-change review offers only back/cancel - internal/tui/runtimewizard.go: name (duplicates rejected), description, shared flag, filterable checklist of unassigned agents (file-seeded agents pre-checked), review; replaces the add/remove/done menu loop - cmd: group and environment wizards delegate to internal/tui; cancel prints "Canceled." instead of failing; remove unused promptMultiSelect wrapper and truncate helper - tests for review helpers and agent list building - docs: group.md and environment.md wizard descriptions; CR-0041 progress
- pickUserGroup, pickAgent, pickAgentService use tui.PickOne - confirmAction replaces 12 duplicated [y/N] confirmation blocks with identical prompt text and behavior (plain line input kept for scripts) - docs: interactive.md confirmations section - CR-0041 acceptance criteria complete; moved to pending
- user update-roles / update-groups: --id|--username (aliases --uid, --uname), --add and --remove (combinable) or --replace (exclusive, empty removes all); de-duplicated, case-insensitive names validated against the org before any change; no-ops reported and skipped; additions before removals; resulting user printed in the --output format - role assignment endpoints match the role display name (verified on dev); commands send the display name and accept role name or display name - user update --interactive edits only group and role assignments and applies them through the V3 assignment endpoints - client: Add/RemoveUserRoles, Add/RemoveUserGroups, PlanMembership with tests - shared printUser used by user get and the new commands - docs: user.md, README, completions; bug record updated with mitigation
- user edit: terminal-only form for user group and role assignments (no --interactive switch needed); applies changes via the V3 add/remove assignment endpoints and prints the resulting user - user update kept as a hidden, deprecated alias of user edit; --interactive accepted and ignored - remove user update --from-file and the V2 scalar update (Client.UpdateUser, updateUserV2Request, doXML, TestUpdateUser): it never worked against the API (HTTP 405 on V3, 400/403 on V2) - docs: user.md "user edit" section, README, interactive.md, completions; CR-0043 updated; user update bug moved to pending
…s API
- client: ObjectACL model (principal {type, name}, permissions {read,
update, delete, execute, changePermission}); list, get, create (POST per
principal), update (PUT per ACL ID), delete one / all, checkAccess;
DiffACLs and ParseACLPermissions with tests. Removes the previous
guessed structs and the non-existent PUT /objects/<id>/permissions
- commands: get, add, update, delete (--acl-id | --user | --group | --all),
set (--from-file, --prune, --dry-run), check (--asset-type); objects by
--object-id or --path/--type (lookup); changes print the resulting ACLs
- verified against dev on a throwaway project
- docs: permission.md rewritten, README, completions; bug moved to pending
- internal/tui/grid: generic grid core extracted from privmatrix (cells, pending-change marks, cursor, row/column toggles, filter with section headers, scrolling, detail footer, clear-row key, action keys, empty text) - privmatrix is now a thin adapter over the grid; role edit unchanged - internal/tui/acleditor.go: EditACLs grid of principals x read/update/ delete/execute/changePermission; n adds a user group or user, d clears a row (ACL deleted); review with +/~/- lines and a warning when your own change permission is removed; returns a DiffACLs plan - permission edit: --object-id, --path/--type, or a project -> folder -> asset picker; checkAccess guard; applies via applyACLPlan (shared with permission set) and prints the resulting ACLs - fix huh cancel hints: Ctrl+C cancels lists (Esc clears the filter) - docs: permission.md edit section, interactive.md, agent.md, README, comparison, completions; CR-0042 moved to pending
- bare "iics" opens a main menu when stdin and stdout are terminals; otherwise prints help as before; opt out with IICS_NO_MENU=1, config ui.menu: false, or CI; "iics menu" (alias tui) opens it explicitly - entries run the real command as a subprocess (terminal passed through, --profile and explicitly set global flags appended), print the command line, show a done/failed status, pause, and return to the last entry; Ctrl+C cancels only the running command - header with profile, org, user and session time from the session cache; session-only profile switch (p) and "Set as default profile" - production profiles (config production: true, or prd/prod name hint) get a red marker and a confirmation before entries that change data; profile add/edit ask for the production flag - first run without profiles starts profile add; accessible mode and small terminals use a numbered line menu - internal/menu with tests (open decision, entries, model, loop with fake runner); config production/UI settings with tests - docs: menu.md, README, interactive.md, profile.md, completions
…ntry - agent installer-download --interactive: OS picker, "Download to" prompt pre-filled with the default temp path (directories and ~/ supported), and an existing-file prompt - existing destination file: SHA-256 compared with the installer checksum and reported; scripts skip a matching file (download otherwise), interactive mode asks (default No when it matches, Yes otherwise), --force always downloads; fetched checksum is reused for --verify - client: SHA256File, CompareChecksum, DownloadOverExisting with tests - menu: "Show agent installer info" entry; download entry runs installer-download --interactive --progress - docs: agent.md, menu.md, CR-0044 follow-up; completions
…CR-0045)
- profile config newUser: domain (default: domain of the profile username),
userNamePattern (default {firstName}.{lastName}.{profileName}@{domain}),
emailPattern (default {firstName}.{lastName}@{domain}); placeholders
firstName, lastName, firstInitial, lastInitial, profileName, domain
- config.ExpandUserPattern validates placeholders and missing values
- user create --interactive: user name and email show the generated value
in gray; right arrow or ctrl+e fills it in for editing, empty uses it;
notes under the field explain the pattern or why there is no suggestion
- profile show lists Production and the effective new-user settings
- tests for pattern defaults/expansion and wizard suggestions
- docs: user.md, profile.md, README; CR-0045 in pending
- menu: "Users > Show user" runs user get - user get without --id/--username on a terminal asks for a user name, ID, or part of a name/email; same prompt replaces the two-step search menu in user edit / user delete - GetUser / GetUserByName use the q=userId== / q=userName== filters instead of listing every user (the API supports exact matches only) - SearchUsers also matches first, last and full name and email; several matches open a filterable picker (user name, name, email, state) - tests updated; docs: user.md (finding a user), menu.md, CR-0044 follow-up
- user create --interactive: leaving the User name field looks up the effective name (typed or suggested) server-side and shows 'user "<name>" already exists (ID <id>)'; cached per name, lookup errors do not block - client: FindUserByName (nil when not found); GetUserByName uses it - tests; docs: user.md, CR-0045 follow-up
IICS rejects removing a user's last directly assigned role with
V3API_IDSError_044 ("The group must have at least one role"), even when
user groups grant other roles.
- user update-roles and user edit reject such a change before any API
call; the edit wizard review cannot be applied in that case
- user update-roles skips additions of roles granted by the user's
groups and reports them on stderr
- the user wizard hides roles granted by the selected groups (except
current direct roles) and lists them in the field description
- document both rules in docs/documentation/user.md
The menu runs in the alternate screen while commands run on the normal screen, which was only cleared after the "Press Enter" pause. The first command showed the shell output from before iics started, and entries that returned to the menu without a pause (profile switch, declined production confirmation, empty prompt) left their prompts above the next command. Clear the screen as soon as an entry is chosen.
- profile add, profile edit, login (missing profile) and first-run setup share one paged form: connection (region list or custom login URL), options, keychain, per-profile new user overrides, review - global newUser defaults with per-field profile overrides; profile show lists effective values and their source - new "iics config edit" for global settings: new user defaults, table theme with preview, header color, colors, responsive tables, HTTP timeout, main menu; menu entry under Session - Config.Save now writes httpTimeout, ui and newUser (profile saves used to drop httpTimeout and ui.menu) - remove the line-based profile prompts and the theme prompt from the profile commands
go install names the binary after the main package directory, so installing from the module root produced iics-cli while release archives, make build and all documentation use iics. - move main.go to cmd/iics/main.go - point Makefile build, install and completions targets at ./cmd/iics - point goreleaser and the CI build job at ./cmd/iics - update the README install command and the directory layout docs - go mod tidy: mark github.com/spf13/pflag as a direct dependency The install command is now: go install github.com/jbrazda/iics-cli/cmd/iics@latest
Add a Session entry that lists the configured profiles and runs 'profile delete <name>' for the picked one. When the active profile is deleted, the menu continues on the default profile, or on the first remaining profile when there is no default.
globalFlagArgs used PersistentFlags().Visit on the root command, but cobra parses on the invoked command's own flag set, so the root set never recorded any flag as set and nothing was passed through. A menu started with --config listed profiles from that file while the commands it ran read ~/.iics/config.yaml. Check Flag.Changed with VisitAll instead.
Add a project markdownlint-cli2 config (no line length limit, repeated headings allowed under different parents, H1 allowed next to a front matter title) and one for .github templates, then fix what is left: table alignment and escaped pipes, code fence languages, hard tabs and blank lines. Also repair two damaged pages: a stray example in activitylog.md that sat outside its code blocks and turned the rest of the page into code, and a leftover fragment of an old user get section in user.md. Test fixtures under testdata/ are not touched.
The hard-coded path only exists on the MacPorts machine. Completed change requests and bug reports keep the old path as historical records.
… (CR-0047) Connections (V2, JSON): - update uses POST /connection/<id>; --partial sends Update-Mode: PARTIAL - create/update send the file as-is and add "@type":"connection" - get --name; new test, search, objects and metadata subcommands - list --type/--name filter client-side (the API ignores them) - Connection struct extended with verified fields Connectors (new): connector list and connector metadata, including attributes parsed from the CCI definition (cciMeta). Projects and folders: - project update uses PATCH by --id or --project-name - folder update percent-encodes names, validates flags and updates by ID via /folders/<id>; --project-id is deprecated (documented /projects/<id>/folders/<id> returns 404) - --interactive pickers driven by the objects API with name filter, plus "Projects and folders" menu entries Response shapes verified against a DEV org; CR moved to pending.
…047) - project list [--name REGEX] [-i] - folder list [--name REGEX] [--project-name | --project-id | --pick-project] [-i] - regex matches the full project/folder path, case-insensitive - created time and created by come from the internal FRS API (/frs/api/v1, IDS-SESSION-ID), user IDs resolved via the users API; falls back to the objects API without the created columns when FRS fails - menu: List projects, List folders, List folders in a project
- huh pickers, text and yes/no prompts: Esc cancels (closes/clears an open filter first), q cancels lists and yes/no prompts but is typed in text inputs and filters; multi-page wizards keep ctrl+c only - [y/N] confirmations, login profile creation, role privilege prompt and the menu pause read single keys in raw mode on a terminal, so arrow keys are ignored instead of echoed as ^[[A; piped answers still work - menu pause: Enter/Esc return to the menu, q/ctrl+c quit
- wizards (user, profile, group, environment, config) and role create cancel with Esc or ctrl+c; q is always typed since they have text inputs - forms run inside a small Bubble Tea model that applies the cancel keys and renders a hint line: "esc, q (in lists) or ctrl+c to cancel" for pickers and questions, "esc or ctrl+c to cancel" for wizards
Read and change Secure Agent service properties of a single agent, such as the Process Server cluster and database settings. There is no REST API for this; the commands use the Administrator form /runtime/app/agent.do with the REST session as USER_SESSION cookie and a double-submit CSRF token, submit the whole form as the browser does, and verify the change by reading back. - agent configs get: filter by service, type, name regex, overridden - agent configs set: --set (value @file), --reset, --from-file, --dry-run, confirmation, refuses agents whose group has group-level properties unless --force, refuses agent system properties (server ignores them) - --debug masks Cookie and Set-Cookie headers
…0049)
- agent configs set --from-file reads JSON or YAML: a nested
service/type/name map (null resets) or a list of {property, value, reset};
only the listed properties change
- agent configs get --export writes the filtered properties in that format
(YAML, or JSON with -o json), so overrides can be copied between agents
- set lists the changed services with 'iics agent restart' commands, since
Process Server keeps the old values until restarted manually
- docs: works for any agent service mix; corrected Process Server restart
behavior
- iics agent rename --id|--fid|--name|--hostname --new-name renames an agent through the agent form (installer registers the host name; standard names are logical, e.g. CAI-A03). Trimmed, max 100 chars, unique in the org, verified with the agent API. - agent configs get hides the agent's own Agent Core / Agent Manager / Tomcat rows (a hidden legacy form section the UI never shows and the server ignores) unless --include-hidden or --service agent is given.
- iics agent configs edit: services -> properties -> property editor -> review and apply, in the style of role edit; agent picker without flags - one-line values in an input; YAML single quotes added back automatically; sensitive values masked - multi-value properties (LDAP, DB connection properties, logging) in an entry editor: edit/add/remove entries, edit as text or in $EDITOR, reset, undo; unchanged entries keep their exact text - review shows entry-level changes for list properties - menu: Environments and agents > Edit agent properties - NAME/PROPERTY columns no longer wrap (renderer moved them last)
- parse custom property rows and the custom types each service offers - agent configs get lists custom properties (OVERRIDDEN shows 'custom') - agent configs set --add / --remove; --set changes a custom value; --reset removes a custom property; --add-missing adds properties from --set/--from-file that do not exist (copying settings between agents) - change files: list items take add/remove/sensitive; null removes customs - type labels from the UI (Tomcat, DTM) are accepted in property names - agent configs edit: + Add custom property, edit value, remove/keep - rows are added after the last custom row with a millisecond ID; the empty template row is replaced or restored like the Administrator UI
…CR-0049) - agent configs set --reset-all [--service]: reset every overridden standard property like the UI's Reset All (custom kept, sensitive skipped) - editor: Reset all to defaults (all services) and per service, with a confirmation listing the properties - agent details -i (or no agent flag in a terminal): pick the agent, then services summary, details, full details or service properties - menu: Environments and agents > Show agent details - agent configs get wraps long property names in the cell instead of falling back to the vertical layout
Recorded against a test org; host names, user names, the organization name and the org ID are masked.
scripts/demo/record.py records docs/demo/iics-demo.cast from scenes.json and masks sensitive output with same-length replacements. The rules live in scripts/demo/masks.local.json, which is ignored by git; masks.example.json documents the format. make demo builds iics, records the cast and renders the GIF with agg.
…errides The Administrator UI now bundles the agent form's property rows into the configFormJson field (POP-88806); posting them as flat parameters exceeds Tomcat's maxParameterCount and the server answers HTTP 500 CMN_001. Pack the rows the same way when the form has that field. Values that differ from the default only in line endings, trailing whitespace or surrounding blank lines are no longer reported as overridden, and whitespace-only sets, sets to the default and resets of non-overridden properties are no longer shown as changes.
Process Server can take well over five minutes to become operational after a start, passing through RUNNING subState -1 and 2 before 0, so restart --blocking timed out with the old 300 second default. start and restart now default --max-wait-time to 1200 seconds (stop keeps 300), poll lines label subStates (-1 Initializing, 2 Starting, 0 Operational), and a timeout reports the last state seen.
The API's customized flag only marks custom properties (Custom Configuration Details); overridden standard properties always come back with customized false. Compute an overridden field from value and default with SameValue, and replace the CUSTOMIZED column with OVERRIDDEN (custom, yes or empty), matching agent configs get.
The skills lived only under the gitignored .claude/ and were copied between machines by hand. Track .claude/skills/ (settings.local.json stays ignored). commit: dev-only branch guard, the full CLAUDE.md check list (gofmt, vet, golangci-lint, tests), docs/completions/CHANGELOG and CR/bug move checks, staging by path instead of git add -A, no Co-Authored-By trailer. release: plain go instead of the MacPorts path, asks before moving pending CRs and bugs, and lands dev on main through a release PR - fast-forward by default (keeps every commit, no back-merge), squash on request - instead of an ff push that only worked through the ruleset bypass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Patch release v0.6.1: agent configuration and service fixes.
Merge method: fast-forward (
git push origin dev:main), keeping every commit.Fixed
agent configs set,agent configs editandagent renamefailed withHTTP 500 after an Administrator UI change. The agent form's property rows
are now sent in the
configFormJsonfield, as the UI sends them.agent configsno longer reports values that differ from the default onlyin line endings or whitespace as overridden. Setting such a value, or
resetting a property that is not overridden, is no longer shown as a
change.
agent restart --blockingandagent start --blockingtimed out whileProcess Server was still starting.
--max-wait-timenow defaults to 1200seconds (20 minutes) for
startandrestart(stopkeeps 300), polllines label subStates (
-1 - Initializing,2 - Starting,0 - Operational), and a timeout reports the last state seen.agent details --fullshowed every property as not customized, because theAPI's
customizedflag only marks custom properties. TheCUSTOMIZEDcolumn is replaced by
OVERRIDDEN(custom,yesor empty), computed fromvalue and default as in
agent configs get, and JSON/YAML output adds anoverriddenfield.🤖 Generated with Claude Code