@aopslabs/aops 0.2.0
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 +19 -0
- package/NOTICE +7 -0
- package/README.md +203 -0
- package/assets/agent-assets/core/SKILL.md +49 -0
- package/assets/agent-assets/core/references/agentspace/SKILL.md +78 -0
- package/assets/agent-assets/core/references/aops-cli-core/SKILL.md +108 -0
- package/assets/agent-assets/core/references/chatv3/SKILL.md +48 -0
- package/assets/agent-assets/core/references/collaborative-work/SKILL.md +85 -0
- package/assets/agent-assets/core/references/discuss/SKILL.md +66 -0
- package/assets/agent-assets/core/references/docman/SKILL.md +69 -0
- package/assets/agent-assets/core/references/hosted-chat/SKILL.md +64 -0
- package/assets/agent-assets/core/references/mission/SKILL.md +54 -0
- package/assets/agent-assets/core/references/projectman/SKILL.md +86 -0
- package/assets/agent-assets/core/references/sys/SKILL.md +36 -0
- package/assets/agent-assets/core/references/view/SKILL.md +58 -0
- package/assets/agent-assets/core/references/working-disciplines/SKILL.md +69 -0
- package/assets/agent-assets/core/user-guides/agent-assets.md +81 -0
- package/assets/agent-assets/core/user-guides/agentspace.md +1098 -0
- package/assets/agent-assets/core/user-guides/aops-cli.md +1107 -0
- package/assets/agent-assets/core/user-guides/aops-system.md +63 -0
- package/assets/agent-assets/core/user-guides/chatv3.md +113 -0
- package/assets/agent-assets/core/user-guides/docman.md +162 -0
- package/assets/agent-assets/core/user-guides/projectman.md +212 -0
- package/assets/agent-assets/core/user-guides/sys.md +94 -0
- package/assets/agent-assets/core/user-guides/working-disciplines.md +588 -0
- package/assets/agent-assets/gateway/aops/SKILL.md +14 -0
- package/assets/r6-remote-session-baseline.json +19 -0
- package/assets/skills/aops-install/SKILL.md +231 -0
- package/assets/skills/aops-install/agents/openai.yaml +4 -0
- package/dist/commands/activity.js +352 -0
- package/dist/commands/agent-profile.js +653 -0
- package/dist/commands/agent.js +710 -0
- package/dist/commands/agents-md.js +125 -0
- package/dist/commands/api.js +84 -0
- package/dist/commands/archive.js +873 -0
- package/dist/commands/artifact.js +535 -0
- package/dist/commands/assets.js +1414 -0
- package/dist/commands/auth/device-login.js +1 -0
- package/dist/commands/auth/legacy-export.js +177 -0
- package/dist/commands/auth/login.js +426 -0
- package/dist/commands/chat.js +1363 -0
- package/dist/commands/chatv3.js +1684 -0
- package/dist/commands/checkpoint.js +549 -0
- package/dist/commands/commercial-artifact.js +475 -0
- package/dist/commands/commercial-license.js +594 -0
- package/dist/commands/community-auth.js +62 -0
- package/dist/commands/community-cockpit.js +185 -0
- package/dist/commands/community-console.js +109 -0
- package/dist/commands/community-doctor.js +335 -0
- package/dist/commands/community-server.js +2062 -0
- package/dist/commands/community-setup.js +284 -0
- package/dist/commands/discuss.js +1448 -0
- package/dist/commands/doc.js +5219 -0
- package/dist/commands/experience.js +922 -0
- package/dist/commands/host.js +1127 -0
- package/dist/commands/init.js +118 -0
- package/dist/commands/memory.js +3129 -0
- package/dist/commands/mission.js +562 -0
- package/dist/commands/official-catalog.js +134 -0
- package/dist/commands/plan.js +84 -0
- package/dist/commands/playbook.js +415 -0
- package/dist/commands/pm/context.js +6 -0
- package/dist/commands/pm/index.js +701 -0
- package/dist/commands/pm/projectman.js +6266 -0
- package/dist/commands/project.js +1080 -0
- package/dist/commands/prompt.js +1024 -0
- package/dist/commands/repo-sync.js +1907 -0
- package/dist/commands/resource.js +527 -0
- package/dist/commands/skill.js +1211 -0
- package/dist/commands/start-disciplines.js +510 -0
- package/dist/commands/start.js +1343 -0
- package/dist/commands/target.js +309 -0
- package/dist/commands/version.js +42 -0
- package/dist/commands/view.js +1852 -0
- package/dist/launchers/cockpit.js +28 -0
- package/dist/launchers/options.js +74 -0
- package/dist/launchers/server.js +41 -0
- package/dist/lib/agent-assets/envelope.js +83 -0
- package/dist/lib/agent-assets/gateway.js +15 -0
- package/dist/lib/agent-assets/guards.js +23 -0
- package/dist/lib/agent-assets/hosted-discovery.js +148 -0
- package/dist/lib/agent-assets/hosted-package-input.js +154 -0
- package/dist/lib/agent-assets/legacy-pointer-migration.js +677 -0
- package/dist/lib/agent-assets/native-fs.js +589 -0
- package/dist/lib/agent-assets/package-manifest.js +324 -0
- package/dist/lib/agent-assets/portable-path.js +67 -0
- package/dist/lib/agent-assets/release-input.js +177 -0
- package/dist/lib/agent-assets/roots.js +45 -0
- package/dist/lib/agent-assets/runtime-binding-reader.js +545 -0
- package/dist/lib/agent-assets/runtime-targets.js +50 -0
- package/dist/lib/agent-assets/store-reader.js +1212 -0
- package/dist/lib/agent-assets/store-types.js +1 -0
- package/dist/lib/agent-assets/store-writer.js +1484 -0
- package/dist/lib/agent-assets/types.js +1 -0
- package/dist/lib/agent-assets/unicode-case-folding-v15-1.generated.js +1548 -0
- package/dist/lib/commercial-final-readiness.js +504 -0
- package/dist/lib/commercial-lifecycle-smoke-isolation.js +236 -0
- package/dist/lib/commercial-managed-postgres-docker-adapter.js +274 -0
- package/dist/lib/commercial-setup-readiness-adapter.js +179 -0
- package/dist/lib/community-client-contract.js +164 -0
- package/dist/lib/community-cockpit-lifecycle.js +601 -0
- package/dist/lib/community-command-abort.js +59 -0
- package/dist/lib/community-diagnostic.js +237 -0
- package/dist/lib/community-docker-adapter.js +498 -0
- package/dist/lib/community-home.js +31 -0
- package/dist/lib/community-instance-contract.js +148 -0
- package/dist/lib/community-instance-layout.js +97 -0
- package/dist/lib/community-lifecycle.js +1631 -0
- package/dist/lib/community-migration-snapshot.js +770 -0
- package/dist/lib/community-native-application-recovery.js +425 -0
- package/dist/lib/community-native-child.js +240 -0
- package/dist/lib/community-native-database-recovery.js +456 -0
- package/dist/lib/community-native-lifecycle.js +2458 -0
- package/dist/lib/community-native-migration.js +339 -0
- package/dist/lib/community-native-postgres.js +596 -0
- package/dist/lib/community-operation-journal.js +773 -0
- package/dist/lib/community-operation-lock.js +596 -0
- package/dist/lib/community-release-resolver.js +291 -0
- package/dist/lib/community-release-verifier.js +475 -0
- package/dist/lib/community-repo-discovery.js +252 -0
- package/dist/lib/community-setup-server-env.js +203 -0
- package/dist/lib/external-url.js +110 -0
- package/dist/lib/official-catalog-gateway.js +108 -0
- package/dist/lib/official-catalog.js +364 -0
- package/dist/lib/server-bootstrap.js +240 -0
- package/dist/lib/setup-agent-assets-bridge.js +176 -0
- package/dist/lib/setup-agent-assets-release.js +52 -0
- package/dist/lib/setup-external-postgres.js +108 -0
- package/dist/lib/setup-init-orchestrator.js +990 -0
- package/dist/lib/setup-install-guide.js +52 -0
- package/dist/lib/setup-installer-release.js +47 -0
- package/dist/lib/setup-local-postgres.js +329 -0
- package/dist/lib/setup-official-catalog-bridge.js +148 -0
- package/dist/lib/setup-readiness.js +888 -0
- package/dist/lib/tui-launcher.js +59 -0
- package/dist/main.js +150 -0
- package/dist/seeds/agents-md.js +54 -0
- package/dist/utils/agent-gateway.js +275 -0
- package/dist/utils/agents-md.js +281 -0
- package/dist/utils/api.js +255 -0
- package/dist/utils/chatv3-session-store.js +185 -0
- package/dist/utils/command.js +67 -0
- package/dist/utils/community-host-runtime.js +376 -0
- package/dist/utils/config.js +1015 -0
- package/dist/utils/discussion-workspace.js +552 -0
- package/dist/utils/experience-workspace.js +326 -0
- package/dist/utils/guide-paths.js +67 -0
- package/dist/utils/hosted-sugar.js +56 -0
- package/dist/utils/hosted-workspace.js +229 -0
- package/dist/utils/memory-workspace.js +537 -0
- package/dist/utils/operator-runtime.js +199 -0
- package/dist/utils/password-crypto.js +39 -0
- package/dist/utils/playbook-workspace.js +479 -0
- package/dist/utils/project-context.js +255 -0
- package/dist/utils/prompts.js +70 -0
- package/dist/utils/refresh-race.js +28 -0
- package/dist/utils/repo-config.js +109 -0
- package/dist/utils/repo-first-projectman.js +194 -0
- package/dist/utils/repo-first-storage.js +13 -0
- package/dist/utils/repo-first-view.js +305 -0
- package/dist/utils/session-guidance.js +278 -0
- package/dist/utils/session-state.js +137 -0
- package/dist/utils/table.js +39 -0
- package/dist/utils/transient-fs.js +49 -0
- package/dist/utils/workspace-root.js +1 -0
- package/launchers/aops-cockpit.ps1 +15 -0
- package/launchers/aops-cockpit.sh +16 -0
- package/launchers/aops-server.ps1 +15 -0
- package/launchers/aops-server.sh +16 -0
- package/native/tui/win32-x64/aops-tui.exe +0 -0
- package/package.json +81 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aops-install
|
|
3
|
+
description: Guide an AI agent through safe AOPS Community npm installation with an existing database, AOPS-managed Docker PostgreSQL, or detected local PostgreSQL; then verify migrations, Gateway assets, server health, and Cockpit. Use for install, initialize, configure, repair, verify, or setup explanation requests after installing @aopslabs/aops.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# AOPS Community installation
|
|
7
|
+
|
|
8
|
+
Use the installed `aops` command as live truth. Run the relevant `--help` before any mutation; do not guess flags from this skill when the installed version differs.
|
|
9
|
+
|
|
10
|
+
## Inspect first
|
|
11
|
+
|
|
12
|
+
If the operator starts with `aops setup ai`, treat its copy-ready prompt as the
|
|
13
|
+
handoff into this packaged skill. The prompt is only an entry point; this skill
|
|
14
|
+
and the installed CLI's live help remain the detailed authority.
|
|
15
|
+
|
|
16
|
+
Run mutation-free discovery:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
aops --version
|
|
20
|
+
aops setup init --yes --json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This setup envelope already includes installation, PostgreSQL, host, and Gateway
|
|
24
|
+
readiness. Read its actions before choosing a path. Run `aops assets status` or
|
|
25
|
+
`aops server status` separately only when that check is action-required and more
|
|
26
|
+
detail is needed.
|
|
27
|
+
|
|
28
|
+
Never place any PostgreSQL URL, application password, path 3 administrator
|
|
29
|
+
password, AuthV2 password, admin key, or token in argv, logs, committed files,
|
|
30
|
+
or chat. Use AOPS masked prompts or the documented private process environment.
|
|
31
|
+
|
|
32
|
+
## Route by need
|
|
33
|
+
|
|
34
|
+
| Need | Smallest surface |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| inspect choices and readiness | `aops setup init --yes --json` |
|
|
37
|
+
| give any terminal AI agent a safe setup handoff | `aops setup ai` |
|
|
38
|
+
| normal operator installation | `aops setup init` |
|
|
39
|
+
| use an existing database URL | path `1`, then `aops setup server-env` |
|
|
40
|
+
| let AOPS manage Docker PostgreSQL | path `2` |
|
|
41
|
+
| create AOPS DB in PostgreSQL on this computer | path `3` |
|
|
42
|
+
| connect only to an existing AOPS server | path `4` |
|
|
43
|
+
| inspect or repair Gateway assets | `aops assets --help` |
|
|
44
|
+
| operate an installed local server | `aops server --help` |
|
|
45
|
+
|
|
46
|
+
Load only the section needed for the selected path. The current nested `--help`
|
|
47
|
+
owns exact flags.
|
|
48
|
+
|
|
49
|
+
## Normal interactive installation
|
|
50
|
+
|
|
51
|
+
Prefer the normal setup menu:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
aops setup init
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
All local-server paths use the normal `default` instance, API port `5900`, and
|
|
58
|
+
independently supervised Cockpit port `5922`, verify
|
|
59
|
+
migrations, install the verified Gateway for registered runtimes, reconcile the inert signed
|
|
60
|
+
official catalog, and leave starter/demo user data untouched. Interactive
|
|
61
|
+
setup applies after collecting the selected path's required private inputs; it
|
|
62
|
+
does not ask redundant continue, asset-selection, or asset-confirmation
|
|
63
|
+
questions. It automatically installs or repairs the verified AOPS core and
|
|
64
|
+
gateway for every registered runtime. The core supplies a small neutral router,
|
|
65
|
+
rich on-demand mounted-domain user guides, and public-safe collaboration and
|
|
66
|
+
working-discipline references. Setup makes disciplines available but does not
|
|
67
|
+
select one. Additional signed catalog packages are imported as discoverable,
|
|
68
|
+
inert choices. Use `--agent-assets skip` or `--no-catalog`
|
|
69
|
+
only when the operator explicitly opts out.
|
|
70
|
+
|
|
71
|
+
Treat the connected database as migration truth. An empty AOPS schema starts
|
|
72
|
+
from migration zero, valid per-domain migration prefixes resume from the next
|
|
73
|
+
entry, and a current schema is verify-only. Do not use an older CLI, release,
|
|
74
|
+
or setup-audit version to decide which migration runs.
|
|
75
|
+
|
|
76
|
+
For automatic Docker PostgreSQL, the container port is loopback-only and dynamically assigned. A destructive reset removes only exact instance/root/secret label-verified resources:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
aops server reset --remove-managed-postgres --confirm-data-loss --confirm-instance default
|
|
80
|
+
aops setup init
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Global AOPS skills and pointers are shared installation assets and remain installed after server reset.
|
|
84
|
+
|
|
85
|
+
The default `trusted-local` server binds only to `127.0.0.1:5900`; it never
|
|
86
|
+
trusts LAN or Tailscale interfaces. AOPS Server on `5900` and Cockpit on `5922`
|
|
87
|
+
are independent services and neither redirects to the other. Community does
|
|
88
|
+
not provide an authenticated non-loopback listener. Use a separate HTTPS
|
|
89
|
+
`remote-session` target for South. When upgrading an old installation, repair
|
|
90
|
+
the private env explicitly with `aops setup server-env --auth trusted-local`;
|
|
91
|
+
the rewrite removes retired local-auth assignments without printing them.
|
|
92
|
+
|
|
93
|
+
## Path safety notes
|
|
94
|
+
|
|
95
|
+
Git clone is a secondary development path. The optional application image is
|
|
96
|
+
built from the same exact public npm CLI/server closure and runs the normal
|
|
97
|
+
`aops server setup` lifecycle inside the container. It is a distribution path,
|
|
98
|
+
not a fifth interactive `setup init` path. Path `2` manages only its namespaced,
|
|
99
|
+
label-verified PostgreSQL resources; unrelated Docker resources remain
|
|
100
|
+
operator-owned.
|
|
101
|
+
|
|
102
|
+
For path `1`, PostgreSQL is operator-owned and may be local, remote, managed,
|
|
103
|
+
or separately containerized. Run interactive `aops setup init` and select path
|
|
104
|
+
`1`; it asks for the PostgreSQL URL using masked input, then immediately tests
|
|
105
|
+
the connection with TLS `require`. A saved URL is offered as a masked default
|
|
106
|
+
on retry and can be kept or replaced. The TLS-policy menu appears only when the
|
|
107
|
+
default encrypted connection fails. Use `verify-full` with a trusted CA and
|
|
108
|
+
matching hostname; use `disable` only when the operator explicitly accepts
|
|
109
|
+
unencrypted transport. For
|
|
110
|
+
non-interactive work, inject `AOPS_PG_URL` privately or prepare it with
|
|
111
|
+
`aops setup server-env`, then inspect `aops setup init --path 1
|
|
112
|
+
--postgres-tls <policy> --yes --json`.
|
|
113
|
+
|
|
114
|
+
For path `3`, prefer interactive setup. It probes loopback PostgreSQL, asks for
|
|
115
|
+
an existing administrator role/password through masked input, creates a new
|
|
116
|
+
dedicated login and database with a generated application password, stores only
|
|
117
|
+
the application URL in the private user server-env, and runs the normal external
|
|
118
|
+
migrations. The administrator password is never stored. If PostgreSQL is absent
|
|
119
|
+
or stopped, return the platform-specific install/start actions reported by
|
|
120
|
+
readiness; do not silently run an elevated package manager. Automation may use
|
|
121
|
+
the private `AOPS_LOCAL_POSTGRES_ADMIN_PASSWORD` environment variable.
|
|
122
|
+
`--local-postgres-admin-no-password` works only with PostgreSQL TCP trust auth;
|
|
123
|
+
it does not bypass authentication or make Linux peer/socket auth work over
|
|
124
|
+
loopback TCP. If the administrator password is unknown, stop and ask the
|
|
125
|
+
operator to configure one through their local PostgreSQL administration flow
|
|
126
|
+
(for example, interactive `sudo -u postgres psql` followed by `\password
|
|
127
|
+
postgres`) before retrying.
|
|
128
|
+
|
|
129
|
+
For path `4`, connect this CLI to an existing AOPS Server without installing or
|
|
130
|
+
operating a local server or PostgreSQL. The interactive wizard asks for the
|
|
131
|
+
endpoint and target name, checks the exact endpoint, persists and selects the
|
|
132
|
+
target, and then offers browser-approved device login when required.
|
|
133
|
+
|
|
134
|
+
External targets require HTTPS with `remote-session` and `system-ca`.
|
|
135
|
+
`authv2-jwt-session` remains a one-release input alias and canonicalizes to
|
|
136
|
+
`remote-session`. Plain HTTP is not a remote-session transport, including on
|
|
137
|
+
Tailscale.
|
|
138
|
+
|
|
139
|
+
Use the target commands when the operator wants explicit add/check/select
|
|
140
|
+
steps:
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
aops target add --name remote --api-base-url https://aops.example.com \
|
|
144
|
+
--auth-provider remote-session --tls-policy system-ca --apply
|
|
145
|
+
aops target doctor remote --json
|
|
146
|
+
aops target use remote --apply
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Run `aops auth login --target remote`; it uses the browser-approved device
|
|
150
|
+
flow and forces a new remote session rather than accepting old local
|
|
151
|
+
credentials. Verify with
|
|
152
|
+
`aops auth status --target remote`; use normal
|
|
153
|
+
`aops auth logout --target remote` to revoke the remote session.
|
|
154
|
+
`--local-only` is an explicit fallback that clears only local credentials when
|
|
155
|
+
remote revocation is unavailable.
|
|
156
|
+
|
|
157
|
+
## Apply explicitly in automation
|
|
158
|
+
|
|
159
|
+
Interactive `aops setup init` applies directly. For agents, CI, and scripts,
|
|
160
|
+
run the selected path's mutation-free readiness first and apply only after its
|
|
161
|
+
required actions and private inputs are understood:
|
|
162
|
+
|
|
163
|
+
```sh
|
|
164
|
+
aops setup init --path 2 --yes --json
|
|
165
|
+
aops setup init --path 2 --plan-id sha256:<64-hex> --apply --yes --json
|
|
166
|
+
|
|
167
|
+
aops setup init --path 3 --yes --json
|
|
168
|
+
aops setup init --path 3 --plan-id sha256:<64-hex> --apply
|
|
169
|
+
|
|
170
|
+
aops setup init --path 4 --api-base-url https://aops.example.com \
|
|
171
|
+
--target-name remote --target-auth-provider remote-session \
|
|
172
|
+
--target-tls-policy system-ca --yes --json
|
|
173
|
+
aops setup init --path 4 --api-base-url https://aops.example.com \
|
|
174
|
+
--target-name remote --target-auth-provider remote-session \
|
|
175
|
+
--target-tls-policy system-ca --apply --yes --json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
For paths 1-3, read `installerPlan.planId` from the mutation-free preview and
|
|
179
|
+
pass that exact value to the apply command. A stale identity fails before any
|
|
180
|
+
setup mutation. Never invent or reuse a plan id from another machine, source,
|
|
181
|
+
path, or readiness snapshot.
|
|
182
|
+
|
|
183
|
+
All paths install the verified Gateway for registered runtimes. Local-server
|
|
184
|
+
paths also reconcile the inert signed official catalog. No path seeds
|
|
185
|
+
starter/demo user data. Use `--agent-assets skip` or `--no-catalog` only for an
|
|
186
|
+
explicit opt-out.
|
|
187
|
+
|
|
188
|
+
If Gateway assets need a separate action, install for every runtime registered by this CLI:
|
|
189
|
+
|
|
190
|
+
```sh
|
|
191
|
+
aops assets install --target all --apply --json
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Use `--target codex`, `--target claude`, comma-separated values such as `--target codex,claude`, or repeat `--target` for an explicit subset. Do not use `both`; it is not a selector.
|
|
195
|
+
|
|
196
|
+
Do not supply a release directory in the normal npm flow. `--from-release` and `--agent-assets-release` are maintainer/offline recovery overrides only. Do not write runtime homes from npm `postinstall`; Gateway writes require the explicit guarded commands above.
|
|
197
|
+
|
|
198
|
+
## Verify and hand off
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
aops server start --json
|
|
202
|
+
aops server health --json
|
|
203
|
+
aops cockpit start --json
|
|
204
|
+
aops cockpit health --json
|
|
205
|
+
aops assets status --verify full --json
|
|
206
|
+
aops cockpit --no-open --json
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
For path `4`, replace the local lifecycle checks with:
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
aops target doctor <target-name> --json
|
|
213
|
+
aops auth status --target <target-name> --json
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
For an operator who wants the server attached to a visible terminal with live
|
|
217
|
+
logs, use the installed package's `launchers/aops-server.sh` on macOS/Linux or
|
|
218
|
+
`launchers/aops-server.ps1` on Windows. It directly invokes the packaged Node
|
|
219
|
+
launcher and Ctrl+C stops that foreground server. The matching
|
|
220
|
+
`aops-cockpit.sh`/`.ps1` starts only the independent Cockpit process and prints
|
|
221
|
+
its URL; it never starts the server implicitly. Do not copy database secrets
|
|
222
|
+
into these scripts or their arguments.
|
|
223
|
+
|
|
224
|
+
Read and report the apply result's migration verification, then report the
|
|
225
|
+
selected path, server health, registered runtime binding states, and the
|
|
226
|
+
separate server and Cockpit URLs. `aops server stop` must not stop Cockpit;
|
|
227
|
+
`aops cockpit stop` must not stop the server. Never report success from process
|
|
228
|
+
exit alone when JSON says
|
|
229
|
+
action-required, conflict, or unhealthy.
|
|
230
|
+
|
|
231
|
+
When setup remains incomplete, preserve the exact safe next action from the CLI output. Ask the operator only for missing authority or private configuration; do not bypass ownership conflicts, TLS decisions, or unknown user-owned runtime files.
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { logError, logSuccess } from '@aopslabs/xf-cli-ui';
|
|
3
|
+
import { applyCommonOptions, compactPayload, normalizeNonEmpty } from '../utils/command.js';
|
|
4
|
+
import { invokeHostedToolWithApiState, requireApiState, unwrapHostedToolResult, } from '../utils/agent-gateway.js';
|
|
5
|
+
import { preferProjectNameBinding, resolveOwnerScopeIdFromBinding, resolveOwnerScopeIdFromProjectRecord, resolveProjectBindingContext, } from '../utils/project-context.js';
|
|
6
|
+
import { buildHostedSugarEnvelope, buildOperatorCookbook, } from '../utils/hosted-sugar.js';
|
|
7
|
+
import { GUIDE_PATHS } from '../utils/guide-paths.js';
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
function unwrapResultData(result) {
|
|
12
|
+
if (isRecord(result) && Object.prototype.hasOwnProperty.call(result, 'data')) {
|
|
13
|
+
return result.data;
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
function toInteger(value, label) {
|
|
18
|
+
if (typeof value === 'number' && Number.isInteger(value))
|
|
19
|
+
return value;
|
|
20
|
+
const normalized = normalizeNonEmpty(value);
|
|
21
|
+
if (!normalized)
|
|
22
|
+
throw new Error(`${label} must be an integer.`);
|
|
23
|
+
const parsed = Number.parseInt(normalized, 10);
|
|
24
|
+
if (!Number.isInteger(parsed))
|
|
25
|
+
throw new Error(`${label} must be an integer.`);
|
|
26
|
+
return parsed;
|
|
27
|
+
}
|
|
28
|
+
function extractId(value) {
|
|
29
|
+
return normalizeNonEmpty(value);
|
|
30
|
+
}
|
|
31
|
+
function collectActivityArtifacts(result) {
|
|
32
|
+
const root = unwrapResultData(result) ?? (isRecord(result) ? result : {});
|
|
33
|
+
const activityItemId = extractId(root?.activityItemId) ?? extractId(root?.id);
|
|
34
|
+
return activityItemId ? { activityItemId } : undefined;
|
|
35
|
+
}
|
|
36
|
+
function jsonByteLength(value) {
|
|
37
|
+
try {
|
|
38
|
+
return Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function summarizeText(value, maxLength = 240) {
|
|
45
|
+
const text = normalizeNonEmpty(value);
|
|
46
|
+
if (!text)
|
|
47
|
+
return undefined;
|
|
48
|
+
if (text.length <= maxLength)
|
|
49
|
+
return text;
|
|
50
|
+
return `${text.slice(0, maxLength - 3)}...`;
|
|
51
|
+
}
|
|
52
|
+
function summarizeUnknown(value) {
|
|
53
|
+
if (value === undefined)
|
|
54
|
+
return undefined;
|
|
55
|
+
if (isRecord(value)) {
|
|
56
|
+
const keys = Object.keys(value).sort();
|
|
57
|
+
return compactPayload({
|
|
58
|
+
kind: 'object',
|
|
59
|
+
keyCount: keys.length,
|
|
60
|
+
keys,
|
|
61
|
+
bytes: jsonByteLength(value),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(value)) {
|
|
65
|
+
return compactPayload({
|
|
66
|
+
kind: 'array',
|
|
67
|
+
length: value.length,
|
|
68
|
+
bytes: jsonByteLength(value),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return compactPayload({
|
|
72
|
+
kind: value === null ? 'null' : typeof value,
|
|
73
|
+
bytes: jsonByteLength(value),
|
|
74
|
+
preview: summarizeText(value, 80),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function summarizeRefs(value) {
|
|
78
|
+
if (value === undefined)
|
|
79
|
+
return undefined;
|
|
80
|
+
if (!Array.isArray(value))
|
|
81
|
+
return summarizeUnknown(value);
|
|
82
|
+
const types = Array.from(new Set(value
|
|
83
|
+
.map((entry) => (isRecord(entry) ? normalizeNonEmpty(entry.type) : undefined))
|
|
84
|
+
.filter((entry) => Boolean(entry)))).sort();
|
|
85
|
+
const preview = value.slice(0, 5).map((entry) => {
|
|
86
|
+
if (!isRecord(entry))
|
|
87
|
+
return entry;
|
|
88
|
+
return compactPayload({
|
|
89
|
+
type: normalizeNonEmpty(entry.type),
|
|
90
|
+
id: normalizeNonEmpty(entry.id),
|
|
91
|
+
label: summarizeText(entry.label, 80),
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
return compactPayload({
|
|
95
|
+
kind: 'array',
|
|
96
|
+
length: value.length,
|
|
97
|
+
types,
|
|
98
|
+
preview,
|
|
99
|
+
previewTruncated: value.length > preview.length ? true : undefined,
|
|
100
|
+
bytes: jsonByteLength(value),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function summarizeActivityRecord(value) {
|
|
104
|
+
if (!isRecord(value))
|
|
105
|
+
return value;
|
|
106
|
+
const summary = normalizeNonEmpty(value.summary);
|
|
107
|
+
const summaryPreview = summarizeText(summary);
|
|
108
|
+
return compactPayload({
|
|
109
|
+
id: normalizeNonEmpty(value.id),
|
|
110
|
+
scopeId: normalizeNonEmpty(value.scopeId),
|
|
111
|
+
projectId: normalizeNonEmpty(value.projectId),
|
|
112
|
+
sourceKind: normalizeNonEmpty(value.sourceKind),
|
|
113
|
+
sourceId: normalizeNonEmpty(value.sourceId),
|
|
114
|
+
action: normalizeNonEmpty(value.action),
|
|
115
|
+
status: normalizeNonEmpty(value.status),
|
|
116
|
+
summary: summaryPreview,
|
|
117
|
+
summaryBytes: summary ? Buffer.byteLength(summary, 'utf8') : undefined,
|
|
118
|
+
summaryTruncated: summary && summaryPreview !== summary ? true : undefined,
|
|
119
|
+
refsSummary: summarizeRefs(value.refs),
|
|
120
|
+
payloadSummary: summarizeUnknown(value.payload),
|
|
121
|
+
metaSummary: summarizeUnknown(value.meta),
|
|
122
|
+
createdAt: normalizeNonEmpty(value.createdAt),
|
|
123
|
+
updatedAt: normalizeNonEmpty(value.updatedAt),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function summarizeActivityListResult(result) {
|
|
127
|
+
if (Array.isArray(result))
|
|
128
|
+
return result.map(summarizeActivityRecord);
|
|
129
|
+
if (isRecord(result) && Array.isArray(result.data)) {
|
|
130
|
+
const data = result.data.map(summarizeActivityRecord);
|
|
131
|
+
return {
|
|
132
|
+
...result,
|
|
133
|
+
data,
|
|
134
|
+
summary: {
|
|
135
|
+
...(isRecord(result.summary) ? result.summary : {}),
|
|
136
|
+
mode: 'activity-list-summary',
|
|
137
|
+
count: data.length,
|
|
138
|
+
omitted: ['refs', 'payload', 'meta'],
|
|
139
|
+
fullRecordHint: 'Use `aops-cli activity get --id <activity-id> --json` without --summary for full refs/payload/meta.',
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return summarizeActivityRecord(result);
|
|
144
|
+
}
|
|
145
|
+
function summarizeActivityGetResult(result) {
|
|
146
|
+
if (isRecord(result) && Object.prototype.hasOwnProperty.call(result, 'data')) {
|
|
147
|
+
return {
|
|
148
|
+
...result,
|
|
149
|
+
data: summarizeActivityRecord(result.data),
|
|
150
|
+
summary: {
|
|
151
|
+
...(isRecord(result.summary) ? result.summary : {}),
|
|
152
|
+
mode: 'activity-get-summary',
|
|
153
|
+
omitted: ['refs', 'payload', 'meta'],
|
|
154
|
+
fullRecordHint: 'Run without --summary for full refs/payload/meta.',
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return summarizeActivityRecord(result);
|
|
159
|
+
}
|
|
160
|
+
function buildGatewayOptions(options, resolvedContext) {
|
|
161
|
+
return {
|
|
162
|
+
...options,
|
|
163
|
+
...preferProjectNameBinding(resolvedContext),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
async function hydrateProjectContext(apiState, options, resolvedContext) {
|
|
167
|
+
const projectId = normalizeNonEmpty(resolvedContext.projectId);
|
|
168
|
+
if (!projectId)
|
|
169
|
+
return resolvedContext;
|
|
170
|
+
if (normalizeNonEmpty(options.scopeId))
|
|
171
|
+
return resolvedContext;
|
|
172
|
+
const payload = await invokeHostedToolWithApiState(apiState, {
|
|
173
|
+
...buildGatewayOptions(options, resolvedContext),
|
|
174
|
+
toolId: 'agentspace.project.get-by-id',
|
|
175
|
+
input: { id: projectId },
|
|
176
|
+
});
|
|
177
|
+
const result = unwrapHostedToolResult(payload);
|
|
178
|
+
const project = unwrapResultData(result);
|
|
179
|
+
if (!isRecord(project))
|
|
180
|
+
return resolvedContext;
|
|
181
|
+
const scopeId = resolveOwnerScopeIdFromProjectRecord(project, resolvedContext.scopeId);
|
|
182
|
+
const projectName = normalizeNonEmpty(project.name) ?? resolvedContext.projectName;
|
|
183
|
+
return {
|
|
184
|
+
...resolvedContext,
|
|
185
|
+
scopeId,
|
|
186
|
+
projectName,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
async function resolveActivityContext(options, apiState) {
|
|
190
|
+
const resolved = await resolveProjectBindingContext(options, {
|
|
191
|
+
requireProject: false,
|
|
192
|
+
});
|
|
193
|
+
const scopeId = normalizeNonEmpty(options.scopeId) ?? resolveOwnerScopeIdFromBinding(resolved);
|
|
194
|
+
return hydrateProjectContext(apiState, options, {
|
|
195
|
+
...resolved,
|
|
196
|
+
scopeId,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function buildResolvedContextRecord(context) {
|
|
200
|
+
return compactPayload({
|
|
201
|
+
repoRoot: context.repoRoot,
|
|
202
|
+
configPath: context.configPath,
|
|
203
|
+
configFound: context.configFound,
|
|
204
|
+
scopeId: context.scopeId,
|
|
205
|
+
projectId: context.projectId,
|
|
206
|
+
projectName: context.projectName,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
const buildEnvelope = buildHostedSugarEnvelope;
|
|
210
|
+
function ensureActivityId(id, label = '--id') {
|
|
211
|
+
const resolved = normalizeNonEmpty(id);
|
|
212
|
+
if (!resolved)
|
|
213
|
+
throw new Error(`Provide ${label}.`);
|
|
214
|
+
return resolved;
|
|
215
|
+
}
|
|
216
|
+
export async function runActivityList(options = {}) {
|
|
217
|
+
try {
|
|
218
|
+
const apiState = await requireApiState(options);
|
|
219
|
+
if (!apiState)
|
|
220
|
+
return;
|
|
221
|
+
const resolvedContext = await resolveActivityContext(options, apiState);
|
|
222
|
+
const input = {
|
|
223
|
+
filter: compactPayload({
|
|
224
|
+
scopeId: normalizeNonEmpty(resolvedContext.scopeId),
|
|
225
|
+
scopeResolution: options.scopeResolution,
|
|
226
|
+
projectId: normalizeNonEmpty(options.filterProjectId),
|
|
227
|
+
sourceKind: normalizeNonEmpty(options.sourceKind),
|
|
228
|
+
sourceId: normalizeNonEmpty(options.sourceId),
|
|
229
|
+
action: normalizeNonEmpty(options.action),
|
|
230
|
+
status: normalizeNonEmpty(options.status),
|
|
231
|
+
}),
|
|
232
|
+
options: compactPayload({
|
|
233
|
+
limit: options.limit !== undefined ? toInteger(options.limit, '--limit') : undefined,
|
|
234
|
+
}),
|
|
235
|
+
};
|
|
236
|
+
const payload = await invokeHostedToolWithApiState(apiState, {
|
|
237
|
+
...buildGatewayOptions(options, resolvedContext),
|
|
238
|
+
tenantId: options.tenantId,
|
|
239
|
+
locale: options.locale,
|
|
240
|
+
fallbackLocale: options.fallbackLocale,
|
|
241
|
+
timeoutMs: options.timeoutMs,
|
|
242
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
243
|
+
accessToken: options.accessToken,
|
|
244
|
+
refreshToken: options.refreshToken,
|
|
245
|
+
toolId: 'agentspace.activity-item.list-activity-items',
|
|
246
|
+
input,
|
|
247
|
+
});
|
|
248
|
+
const result = unwrapHostedToolResult(payload);
|
|
249
|
+
const outputResult = options.summary ? summarizeActivityListResult(result) : result;
|
|
250
|
+
if (options.json) {
|
|
251
|
+
console.log(JSON.stringify(buildEnvelope({
|
|
252
|
+
command: 'activity.list',
|
|
253
|
+
toolId: 'agentspace.activity-item.list-activity-items',
|
|
254
|
+
resolvedContext: buildResolvedContextRecord(resolvedContext),
|
|
255
|
+
input,
|
|
256
|
+
result: outputResult,
|
|
257
|
+
}), null, 2));
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
logSuccess('Activity list loaded.');
|
|
261
|
+
console.log(JSON.stringify(outputResult, null, 2));
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
logError(error instanceof Error ? error.message : String(error));
|
|
265
|
+
process.exitCode = 1;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export async function runActivityGet(options = {}) {
|
|
269
|
+
try {
|
|
270
|
+
const apiState = await requireApiState(options);
|
|
271
|
+
if (!apiState)
|
|
272
|
+
return;
|
|
273
|
+
const resolvedContext = await resolveActivityContext(options, apiState);
|
|
274
|
+
const id = ensureActivityId(options.id);
|
|
275
|
+
const input = { id };
|
|
276
|
+
const payload = await invokeHostedToolWithApiState(apiState, {
|
|
277
|
+
...buildGatewayOptions(options, resolvedContext),
|
|
278
|
+
tenantId: options.tenantId,
|
|
279
|
+
locale: options.locale,
|
|
280
|
+
fallbackLocale: options.fallbackLocale,
|
|
281
|
+
timeoutMs: options.timeoutMs,
|
|
282
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
283
|
+
accessToken: options.accessToken,
|
|
284
|
+
refreshToken: options.refreshToken,
|
|
285
|
+
toolId: 'agentspace.activity-item.get-by-id',
|
|
286
|
+
input,
|
|
287
|
+
});
|
|
288
|
+
const result = unwrapHostedToolResult(payload);
|
|
289
|
+
const outputResult = options.summary ? summarizeActivityGetResult(result) : result;
|
|
290
|
+
if (options.json) {
|
|
291
|
+
console.log(JSON.stringify(buildEnvelope({
|
|
292
|
+
command: 'activity.get',
|
|
293
|
+
toolId: 'agentspace.activity-item.get-by-id',
|
|
294
|
+
resolvedContext: buildResolvedContextRecord(resolvedContext),
|
|
295
|
+
input,
|
|
296
|
+
artifacts: collectActivityArtifacts(result),
|
|
297
|
+
result: outputResult,
|
|
298
|
+
}), null, 2));
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
logSuccess('Activity item loaded.');
|
|
302
|
+
console.log(JSON.stringify(outputResult, null, 2));
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
logError(error instanceof Error ? error.message : String(error));
|
|
306
|
+
process.exitCode = 1;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function applyActivityContextOptions(cmd, params = {}) {
|
|
310
|
+
applyCommonOptions(cmd);
|
|
311
|
+
cmd.option('--project-id <id>', 'Project id used to resolve repo-bound activity ownership');
|
|
312
|
+
cmd.option('--project-name <name>', 'Project name used to resolve repo-bound activity ownership');
|
|
313
|
+
cmd.option('--scope-id <id>', 'Explicit scope id override for activity ownership');
|
|
314
|
+
if (params.withScopeResolution) {
|
|
315
|
+
cmd.option('--scope-resolution <mode>', 'Scope resolution policy: explicit or cascade');
|
|
316
|
+
}
|
|
317
|
+
return cmd;
|
|
318
|
+
}
|
|
319
|
+
export function makeActivityCommand() {
|
|
320
|
+
const cmd = new Command('activity').description('Agentspace activity ledger read sugar over the hosted AOPS gateway');
|
|
321
|
+
applyActivityContextOptions(cmd.command('list')
|
|
322
|
+
.description('List activity ledger items')
|
|
323
|
+
.option('--source-kind <kind>', 'Source kind filter: aops-cli, desktop, runner, system')
|
|
324
|
+
.option('--source-id <id>', 'Source id filter')
|
|
325
|
+
.option('--action <text>', 'Action filter')
|
|
326
|
+
.option('--status <status>', 'Status filter: success or error')
|
|
327
|
+
.option('--filter-project-id <id>', 'Activity projectId filter; separate from context --project-id')
|
|
328
|
+
.option('--limit <n>', 'Optional item limit')
|
|
329
|
+
.option('--summary', 'Print compact activity records and omit raw refs/payload/meta'), { withScopeResolution: true }).action(async (options) => {
|
|
330
|
+
await runActivityList(options);
|
|
331
|
+
});
|
|
332
|
+
applyActivityContextOptions(cmd.command('get')
|
|
333
|
+
.description('Get an activity ledger item by id')
|
|
334
|
+
.requiredOption('--id <id>', 'Activity item id')
|
|
335
|
+
.option('--summary', 'Omit raw refs/payload/meta and print compact size summaries')).action(async (options) => {
|
|
336
|
+
await runActivityGet(options);
|
|
337
|
+
});
|
|
338
|
+
cmd.addHelpText('after', buildOperatorCookbook({
|
|
339
|
+
examples: [
|
|
340
|
+
'aops-cli activity list --summary --limit 20 --json',
|
|
341
|
+
'aops-cli activity list --source-kind aops-cli --status success --summary --json',
|
|
342
|
+
'aops-cli activity get --id <activity-id> --summary --json',
|
|
343
|
+
],
|
|
344
|
+
guide: GUIDE_PATHS.agentspace,
|
|
345
|
+
notes: [
|
|
346
|
+
'Activity commands are read-only and do not require --apply.',
|
|
347
|
+
'Use --summary for inventories because activity refs, payload, and meta can be large.',
|
|
348
|
+
'Use `aops-cli agent tools --domain agentspace --q activity --summary --json` for raw hosted operations not covered by this sugar.',
|
|
349
|
+
],
|
|
350
|
+
}));
|
|
351
|
+
return cmd;
|
|
352
|
+
}
|