chore: project scaffold for access-datamacro sync

This commit is contained in:
Misaka_Company
2026-07-14 11:12:34 +08:00
commit fb025bb061
14 changed files with 2092 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
---
name: nssm-114
description: NSSM (Non-Sucking Service Manager) operations and Windows service maintenance targeting the internal host 114. Use this skill whenever the user mentions NSSM, nssm.exe, or any nssm command (install, remove, set, get, reset, dump, start, stop, restart, pause, continue, rotate, status), or asks to manage/configure/restart a Windows service that you know or suspect is an NSSM-wrapped service. Also use it when the user says "运维/管理/重启/查一下服务" in connection with 114 or an internal service. In this environment, NSSM-related ops ALWAYS target host 114 (SSH alias `114`) — never run nssm locally. Route everything through `ssh 114 "..."`.
---
# NSSM Ops on Host 114
## The core routing rule
**Every NSSM operation targets host 114 over SSH.** Never run `nssm` on the local machine.
- SSH alias: `114` (Windows Server host, non-interactive)
- All commands go through: `ssh 114 "nssm <subcommand> ..."` or `ssh 114 "cmd /c ..."` / `ssh 114 "powershell -Command \"...\""`
- If the user says "114" + anything about services, or just "查一下/重启一下服务" with NSSM context, that's host 114.
## How SSH to 114 actually works (read this before running anything)
This is the part that bites. SSH to 114 is **non-interactive**:
1. **No session.** Each `ssh 114 "..."` is a one-shot. `stdin` is not a TTY, so you cannot open an interactive shell and type follow-ups. Run one command per invocation, or chain with `&&` / `;`.
2. **`Pseudo-terminal will not be allocated`** warnings are normal — ignore them.
3. **Bash double-quote escaping eats PowerShell `$` variables.** When you run `ssh 114 "powershell -Command \"... $_ ...\""`, bash mangles `$_` and `$var` into `\extglob` garbage, producing hundreds of errors. This is the #1 source of broken commands.
- **Avoid `$_`, `$PSItem`, and any `$var` in PowerShell sent over SSH-through-bash.**
- Prefer plain `cmd.exe` tools: `findstr`, `where`, `dir`, `type`, `reg query`.
- If you need PowerShell, avoid pipeline `$_` (use `Where-Object`/`ForEach-Object` scriptblocks that don't reference `$_`, or filter in cmd).
- For complex logic, write a `.ps1` or `.py` file to the host first (via scp or a heredoc), then run it. Don't try to cram multi-line PowerShell into a quoted `-Command`.
4. **Verify command output.** Many `nssm` subcommands print `操作成功完成` / `Set parameter ... for service ...` on success. Read what comes back before declaring done.
## Listing services (always start here when scope is unclear)
```
ssh 114 "nssm list"
```
This enumerates all NSSM-managed services on the host. If the user says "查一下服务" / "有哪些服务", run this first.
## The NSSM command reference (essentials)
Full official command reference is bundled at `references/nssm-commands.md` — read it when you need exact syntax, subparameters, or less-common parameters. The everyday set:
### Lifecycle
```
nssm install <servicename> <program> [<arguments>] # install
nssm remove <servicename> [confirm] # uninstall (confirm skips prompt)
nssm start <servicename>
nssm stop <servicename>
nssm restart <servicename>
nssm status <servicename> # 0=stopped, 1=running, etc.
```
### Inspect config
```
nssm dump <servicename> # full config as nssm set commands (great for snapshots)
nssm get <servicename> <parameter> [<subparameter>]
```
### Edit config
```
nssm set <servicename> <parameter> [<subparameter>] <value>
nssm reset <servicename> <parameter> [<subparameter>] # back to default / delete reg entry
```
Common parameters: `Application`/`AppProgram`, `AppParameters`, `AppDirectory`, `AppStdout`, `AppStderr`, `AppExit`, `AppEnvironmentExtra`, `AppEnvironment`, `AppRotateFiles`, `AppRotateBytes`, `AppRotateOnline`, `Description`, `DisplayName`, `ObjectName`, `Start`, `Type`, `DependOnService`.
### Service controls
```
nssm pause <servicename> # SERVICE_PAUSE_PENDING capable
nssm continue <servicename>
nssm rotate <servicename> # online log rotation (needs AppRotateFiles + AppRotateOnline)
```
## NSSM gotchas (these will save you)
### Gotcha 1 — `AppEnvironmentExtra` replaces, it does not append
`nssm set <svc> AppEnvironmentExtra <value>` writes the **entire** environment block. Calling it multiple times in a row (e.g. chained with `&&`) wipes everything except the last value. The official docs confirm:
> When setting an environment block with `nssm set`, each variable should be specified as a KEY=VALUE pair in a separate argument.
**Correct — all variables in ONE call:**
```
nssm set <svc> AppEnvironmentExtra VAR1=v1 VAR2=v2 VAR3=v3
```
**Wrong — only VAR3 survives:**
```
nssm set <svc> AppEnvironmentExtra VAR1=v1 && nssm set <svc> AppEnvironmentExtra VAR2=v2 && nssm set <svc> AppEnvironmentExtra VAR3=v3
```
Before adding env vars, snapshot the current block so you can include existing entries:
```
ssh 114 "nssm get <svc> AppEnvironmentExtra" # or: reg query ...\Parameters /v AppEnvironmentExtra
```
### Gotcha 2 — what `nssm dump` prefixes mean
`nssm dump <svc>` prints each env var with a prefix that encodes its semantics:
- `:NAME=value`**conditional**: set only if not already present in the process environment. Won't override a value inherited from the machine/user environment.
- `+NAME=value`**override**: force-set, replacing any inherited value.
The raw registry (`reg query`) stores values without these prefixes; the prefix is NSSM's display convention. If you need a service-level env var to **override** a machine-level one (very common for proxies), make sure it shows as `+` in `nssm dump`, i.e. write it without a leading `:` in the `nssm set` value.
### Gotcha 3 — restart to apply env/log/path changes
`nssm set` only edits the registry. The running process won't pick up `AppParameters`, `AppDirectory`, `AppEnvironmentExtra`, log paths, etc. until you **restart** the service. Snapshot logs first if the service is mid-task:
```
ssh 114 "nssm restart <svc>"
```
### Gotcha 4 — LocalSystem vs user-account services
Most NSSM services run as `LocalSystem`, which can't access network shares or the current user's profile/credentials. If a service needs LAN file access, it runs as a real account (e.g. `.\peng`). Check with `nssm get <svc> ObjectName` before assuming network access works the same way as your shell.
## Working safely on a production host
114 runs real services. Before mutating state:
1. **Snapshot first.** `nssm dump <svc> > before.txt` (or capture relevant `nssm get` output) so you have an exact rollback recipe.
2. **One change at a time**, verify output, then move on.
3. **Prefer `nssm restart`** over stop+start; it's atomic from NSSM's perspective.
4. **Tail logs** after changes: `nssm get <svc> AppStdout` / `AppStderr` to find the log paths, then read the tail for new errors.
5. **Rollback** = re-run the snapshot's `nssm set` lines, or `nssm reset` the parameter, then restart.
## When to read the bundled reference
Read `references/nssm-commands.md` when you need:
- Exact subparameter syntax for `AppExit`, `AppEnvironment(Extra)`, `DependOnService`, `ObjectName`, `Start`, `Type`
- The full list of native vs non-standard parameters
- Priority class constants for `AppPriority`
- Confirmation that a parameter exists before guessing
Do NOT read it for the everyday lifecycle/config commands above — those are the hot path.

View File

@@ -0,0 +1,29 @@
{
"skill_name": "nssm-114",
"evals": [
{
"id": 1,
"name": "list-services-readonly",
"prompt": "114上有哪些nssm服务列一下",
"expected_output": "通过 ssh 114 \"nssm list\" 列出服务清单不执行任何写操作遵循非交互SSH约定",
"files": [],
"safety": "READ-ONLY — safe to actually run against 114"
},
{
"id": 2,
"name": "inspect-config-readonly",
"prompt": "帮我看一下 114 上 WebTable 这个服务的完整配置,日志轮转开了吗",
"expected_output": "用 ssh 114 \"nssm dump WebTable\" 拿到完整配置;解读 AppRotateFiles/AppRotateBytes/AppRotateOnline指出日志路径遵循SSH坑约束",
"files": [],
"safety": "READ-ONLY — safe to actually run against 114"
},
{
"id": 3,
"name": "mutating-env-config",
"prompt": "给 114 上某个服务加一个环境变量 FOO=bar和它已有的 PYTHONUTF8=1 共存",
"expected_output": "先 nssm get <svc> AppEnvironmentExtra 看现状;正确地用单条 nssm set 同时传 PYTHONUTF8=1 和 FOO=bar避免覆盖丢失坑提醒改完要 restart不实际执行破坏性写入或先快照",
"files": [],
"safety": "MUTATING — eval subagent would write to production. Recommend NOT auto-running; review guidance only."
}
]
}

View File

@@ -0,0 +1,28 @@
# NSSM Services on Host 114
## Command Run
```
ssh 114 "nssm list"
```
This is the canonical read-only enumeration command per the skill. No stdin/TTY interaction, no PowerShell `$` variables involved, so no escaping hazards.
## Output (the list of NSSM-managed services)
```
BLD_IncrementalSync
CargotraceFastAPIService
ExcelToSqlServer
WarehouseQuery
WebTable
```
5 NSSM-managed services total.
## SSH Behavior Notes
- Single one-shot `ssh 114 "nssm list"` invocation — no interactive shell, no follow-up commands needed.
- No `Pseudo-terminal will not be allocated` warning appeared in this run, but per the skill it would be safe to ignore if it had.
- No PowerShell involved, so the `$_` / `$var` mangling gotcha does not apply.
- `nssm list` printed one service name per line with no extra header/footer — clean output.

View File

@@ -0,0 +1 @@
{"total_tokens": 45, "duration_ms": 38890, "total_duration_seconds": 38.9}

View File

@@ -0,0 +1,58 @@
# WebTable Service Inspection on Host 114
## Commands Ran (all read-only)
```
ssh 114 "nssm dump WebTable"
ssh 114 "nssm status WebTable"
ssh 114 "nssm get WebTable AppRotateFiles & nssm get WebTable AppRotateBytes & nssm get WebTable AppRotateOnline & nssm get WebTable AppRotateSeconds"
```
## Full Config (`nssm dump WebTable`)
```
nssm install WebTable "C:\Program Files\nodejs\npx.cmd"
nssm set WebTable AppParameters "next start -H 0.0.0.0 -p 3081"
nssm set WebTable AppDirectory C:\Users\peng\projects\ProductionDatabase\web-table
nssm set WebTable AppExit Default Restart
nssm set WebTable AppStdout C:\Users\peng\projects\ProductionDatabase\web-table\logs\stdout.log
nssm set WebTable AppStderr C:\Users\peng\projects\ProductionDatabase\web-table\logs\stderr.log
nssm set WebTable DisplayName WebTable
nssm set WebTable ObjectName LocalSystem
nssm set WebTable Start SERVICE_AUTO_START
nssm set WebTable Type SERVICE_WIN32_OWN_PROCESS
```
## Service Status
```
SERVICE_RUNNING
```
## Log Rotation Parameters
| Parameter | Value | Meaning |
|--------------------|-------|----------------------------------|
| `AppRotateFiles` | `0` | Rotation disabled (no file rotation) |
| `AppRotateBytes` | `0` | No byte-size threshold set |
| `AppRotateOnline` | `0` | Online rotation disabled |
| `AppRotateSeconds` | `0` | No time-based rotation threshold |
## Answer: Is Log Rotation Enabled?
**No. Log rotation is fully disabled for WebTable.**
All four rotation-related parameters are `0`:
- `AppRotateFiles = 0` — NSSM will not rotate log files at all.
- `AppRotateBytes = 0` — no size threshold configured.
- `AppRotateOnline = 0` — online rotation not enabled.
- `AppRotateSeconds = 0` — no time-based rotation configured.
The `nssm dump` output also omits any `AppRotate*` lines, confirming these are all at their default (unset/disabled) state. Logs are written directly to `C:\Users\peng\projects\ProductionDatabase\web-table\logs\stdout.log` and `stderr.log` and will grow without limit.
## SSH Behavior Notes
- All three SSH commands completed successfully in a single one-shot invocation each (non-interactive, as documented in the skill).
- The `Pseudo-terminal will not be allocated` warning did not appear in this run, but is expected and harmless.
- Chaining four `nssm get` calls with `&` in a single SSH invocation worked correctly on the Windows host's cmd.exe, returning four lines of output in order.
- No PowerShell `$_` issues were encountered because all commands used plain `nssm` CLI (cmd.exe-native), per the skill's recommendation to prefer cmd tools over PowerShell over SSH.

View File

@@ -0,0 +1 @@
{"total_tokens": 116, "duration_ms": 93003, "total_duration_seconds": 93.0}

View File

@@ -0,0 +1,257 @@
# NSSM Commands
> Source: <https://nssm.cc/commands>
## Managing services from the command line
NSSM's core functionality has always been available from the command line.
## Service installation
```
nssm install
nssm install <servicename>
nssm install <servicename> <program>
nssm install <servicename> <program> [<arguments>]
```
By default the service's startup directory will be set to the directory containing the `program`. The startup directory can be overridden after the service has been installed.
```
nssm set <servicename> AppDirectory <path>
```
## Service removal
```
nssm remove
nssm remove <servicename>
nssm remove <servicename> confirm
```
## Service management
As of version 2.22, NSSM offers basic service management functionality. NSSM will also accept a service `displayname` anywhere that a `servicename` is expected, since Windows does not allow a service to have a name or display name which conflicts with either the name or display name of another service. Both the service name (also called the service key name) and its display name uniquely identify a service.
### Starting and stopping a service
```
nssm start <servicename>
nssm stop <servicename>
nssm restart <servicename>
```
### Querying a service's status
```
nssm status <servicename>
```
### Sending controls to services
```
nssm pause <servicename>
nssm continue <servicename>
nssm rotate <servicename>
```
`nssm rotate` triggers on-demand rotation for NSSM services with I/O redirection and online rotation enabled. NSSM accepts user-defined control 128 as a cue to begin output file rotation. Non-NSSM services might respond to control 128 in their own way (or ignore it, or crash).
## Service editing
As of version 2.22, **all** parameters understood by NSSM can be queried or configured on the command line. A subset of system parameters can also be queried and, in some cases, modified.
### General syntax
Parameters can usually be queried as follows.
```
nssm get <servicename> <parameter>
```
Some parameters are ambiguous and require a subparameter. See below.
```
nssm get <servicename> <parameter> <subparameter>
```
Parameters can usually be set in a similar way.
```
nssm set <servicename> <parameter> <value>
nssm set <servicename> <parameter> <subparameter> <value>
```
Most parameters can be reset to their defaults, which is equivalent to removing the associated registry entry.
```
nssm reset <servicename> <parameter>
nssm reset <servicename> <parameter> <subparameter>
```
As a convenience, NSSM will accept additional arguments beyond the `value` required, and concatenate them together, separated by single spaces. Thus the following two invocations are identical:
```
nssm set <servicename> AppParameters "-classpath C:\Classes"
nssm set <servicename> AppParameters -classpath C:\Classes
```
### Parameters
A `parameter` is usually a string with the same name as the registry entry which controls the associated functionality. So, for example, the following command sets the startup directory for a service:
```
nssm set <servicename> AppDirectory <path>
```
### Values
Most parameters are configured by setting the same value as is documented for the associated registry entry. To enable file rotation, for example, you would use the following command:
```
nssm set <servicename> AppRotation 1
```
See below for a list of parameters whose values are set differently.
### Native parameters
Certain parameters configure properties of the service itself rather than the behaviour of NSSM. They too are named after their associated registry values.
- **DependOnGroup:** Load order groups whose members must start before the service can start.
- **DependOnService:** Services which must start before the service can start.
- **Description:** The service's description.
- **DisplayName:** The service's display name, eg *Application Layer Gateway Service*. This is the name shown under the *Name* column in *services.msc*.
- **ImagePath:** Path to the service executable, eg *C:\Windows\System32\alg.exe*. For NSSM services, this will be the path to *nssm.exe*.
- **ObjectName:** The name of the user account under which the service runs. The default is *LOCALSYSTEM*.
- **Name:** The service key name, eg *ALG*. The key name cannot be changed. You can use `nssm get <servicename> Name` to find out the key name of a service.
- **Start:** The service's startup type, eg *Automatic*.
- **Type:** The service type. NSSM can only edit services of type `SERVICE_WIN32_OWN_PROCESS`.
### Non-standard parameters
- When used with `nssm get`, **AppEnvironment** and **AppEnvironmentExtra** accept an optional subparameter. If no subparameter is given, `nssm get` will print all configured environment variables, one per line in the form *KEY=VALUE*. If a subparameter is given, `nssm get` will print the value configured for the named environment variable, or the empty string if that variable is not present in the environment block.
For example, suppose that **AppEnvironmentExtra** were configured with two variables, *CLASSPATH=C:\Classes* and *TEMP=C:\Temp*. The following invocation:
```
nssm get <servicename> AppEnvironmentExtra
```
would print:
```
CLASSPATH=C:\Classes
TEMP=C:\Temp
```
Whereas the syntax below:
```
nssm get <servicename> AppEnvironmentExtra CLASSPATH
```
would print:
```
C:\Classes
```
When setting an environment block with `nssm set`, each variable should be specified as a *KEY=VALUE* pair in a separate argument. For example:
```
nssm set <servicename> AppEnvironmentExtra CLASSPATH=C:\Classes TEMP=C:\Temp
```
- The **AppExit** parameter requires a subparameter specifying the exit code to get or set. The default action can be specified with the string *Default*.
For example, to get the default exit action for a service you should run:
```
nssm get <servicename> AppExit Default
```
To get the exit action when the application exits with exit code 2, run:
```
nssm get <servicename> AppExit 2
```
Note that if no explicit action is configured for a specified exit code, NSSM will print the default exit action.
To configure the service to stop when the application exits with an exit code of 2, run:
```
nssm set <servicename> AppExit 2 Exit
```
- The **AppPriority** parameter takes a priority class constant as specified in the `SetPriorityClass()` documentation. Valid priorities are:
- *REALTIME_PRIORITY_CLASS*
- *HIGH_PRIORITY_CLASS*
- *ABOVE_NORMAL_PRIORITY_CLASS*
- *NORMAL_PRIORITY_CLASS*
- *BELOW_NORMAL_PRIORITY_CLASS*
- *IDLE_PRIORITY_CLASS*
### Non-standard native parameters
- When used with `nssm set`, the **DependOnGroup** and **DependOnService** parameters treat each subsequent command line argument as a dependency group or service.
Groups can be specified with or without the `SC_GROUP_IDENTIFIER` prefix (the *+* symbol). Services can be specified via their key name or display name.
The following two invocations are equivalent:
```
nssm set <servicename> DependOnService RpcSS LanmanWorkstation
nssm set <servicename> DependOnService "Remote Procedure Call (RPC)" LanmanWorkstation
```
Groups will always be prefixed by the `SC_GROUP_IDENTIFIER` when queried with `nssm get`.
- When used with `nssm set`, the **ObjectName** parameter requires an additional argument specifying the password of the user which will run the service.
To retrieve the username, run:
```
nssm get <servicename> ObjectName
```
To set the username and password, run:
```
nssm set <servicename> ObjectName <username> <password>
```
Note that the rules of argument concatenation still apply. The following invocation will have the expected effect:
```
nssm set <servicename> ObjectName <username> correct horse battery staple
```
If you absolutely must configure an account with a blank password, run:
```
nssm set <servicename> ObjectName <username> ""
```
- Valid values for the **Start** parameter are:
- *SERVICE_AUTO_START:* Automatic startup at boot.
- *SERVICE_DELAYED_AUTO_START:* Delayed startup at boot.
- *SERVICE_DEMAND_START:* Manual startup.
- *SERVICE_DISABLED:* Service is disabled.
Note that *SERVICE_DELAYED_AUTO_START* is not supported on versions of Windows prior to Vista. NSSM will set the service to automatic startup if delayed start is unavailable.
- The **Type** parameter is used to query or set the service type. NSSM recognises all currently documented service types but will only allow setting one of two types:
- *SERVICE_WIN32_OWN_PROCESS:* A standalone service. This is the default.
- *SERVICE_INTERACTIVE_PROCESS:* A service which can interact with the desktop.
A service may only be configured as interactive if it runs under the *LOCALSYSTEM* account. To guarantee success when attempting to configure an interactive service, run two commands in sequence:
```
nssm reset <servicename> ObjectName
nssm set <servicename> Type SERVICE_INTERACTIVE_PROCESS
```