@steercards/agent-tools 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -16,7 +16,7 @@ Steercards의 전체 MCP 도구를 CLI와 에이전트에서 사용할 수 있
16
16
  ```sh
17
17
  npm ci
18
18
  npm run build
19
- node /absolute/path/agent-tools/dist/cli.js setup --client codex-app --cwd /absolute/path/project --local
19
+ node -- /absolute/path/agent-tools/dist/cli.js setup --client codex-app --cwd /absolute/path/project --local
20
20
  ```
21
21
 
22
22
  `setup` 한 번으로 Steercards MCP 설정과 Skill을 함께 설치합니다. 키 없이 설치할 수 있으며 `.env`를 만들거나 덮어쓰지 않습니다. 설치 뒤 프로젝트에 `.env.example`을 참고한 `.env`를 만들고 실제 Agent Key를 입력하세요.
@@ -32,7 +32,7 @@ STEERCARDS_MCP_URL=https://steercards.com/api/mcp
32
32
  클라이언트에서 필요한 MCP 승인과 재시작·다시 연결을 마친 뒤 확인합니다.
33
33
 
34
34
  ```sh
35
- node /absolute/path/agent-tools/dist/cli.js doctor --cwd /absolute/path/project --connect
35
+ node -- /absolute/path/agent-tools/dist/cli.js doctor --cwd /absolute/path/project --connect
36
36
  ```
37
37
 
38
38
  `doctor`는 키 값을 출력하지 않습니다. `--connect`를 추가하면 원격 서버에 연결하고 워크스페이스 목록을 조회하는 읽기 전용 검사를 수행합니다. 생략하면 로컬 설정만 확인합니다.
@@ -42,7 +42,7 @@ node /absolute/path/agent-tools/dist/cli.js doctor --cwd /absolute/path/project
42
42
  처음 설치할 때와 새 버전으로 업데이트할 때 같은 명령을 사용합니다.
43
43
 
44
44
  ```sh
45
- npx -y @steercards/agent-tools@latest setup --client codex-app --cwd /absolute/path/project
45
+ npx -y -- @steercards/agent-tools@latest setup --client codex-app --cwd /absolute/path/project
46
46
  ```
47
47
 
48
48
  실행한 패키지 버전의 MCP 설정과 Skill을 함께 적용합니다. npx 기반 MCP 실행 명령은 해당 버전에 고정되므로 Skill과 같은 버전을 사용합니다. 같은 버전·옵션으로 다시 실행하면 변경 없이 성공합니다. 기존 설치에서는 생략한 실행 옵션(`--local`, `--mode`, `--url`, `--env-file`)을 설치 기록에서 유지합니다. `--local` 설치는 새 소스를 받은 뒤 `npm ci`, `npm run build`를 실행하고 같은 `setup --local` 명령을 다시 실행하세요.
@@ -50,7 +50,7 @@ npx -y @steercards/agent-tools@latest setup --client codex-app --cwd /absolute/p
50
50
  소스의 `--local` 설치를 npm 실행 방식으로 전환할 때는 `--npx`를 지정합니다. 이후 MCP 설정은 실행한 패키지 버전의 npx 명령을 사용합니다.
51
51
 
52
52
  ```sh
53
- npx -y @steercards/agent-tools@latest setup --client codex-app --cwd /absolute/path/project --npx
53
+ npx -y -- @steercards/agent-tools@latest setup --client codex-app --cwd /absolute/path/project --npx
54
54
  ```
55
55
 
56
56
  전역 설치를 선택했다면 패키지를 업데이트한 뒤 `setup`을 다시 실행합니다.
@@ -60,7 +60,7 @@ npm install --global @steercards/agent-tools@latest
60
60
  steercards setup --client codex-app --cwd /absolute/path/project
61
61
  ```
62
62
 
63
- 이하 `steercards` 명령은 전역 설치를 기준으로 합니다. 소스 빌드 사용자는 `node /absolute/path/agent-tools/dist/cli.js`로 대체하면 됩니다.
63
+ 이하 `steercards` 명령은 전역 설치를 기준으로 합니다. 소스 빌드 사용자는 `node -- /absolute/path/agent-tools/dist/cli.js`로 대체하면 됩니다.
64
64
 
65
65
  ## 환경 설정
66
66
 
@@ -74,6 +74,15 @@ steercards setup --client codex-app --cwd /absolute/path/project
74
74
 
75
75
  이미 설정된 프로세스 환경 변수가 `.env`보다 우선합니다. 기본 `.env`는 지정한 디렉터리에서만 찾으며 상위 디렉터리를 탐색하지 않습니다. dotenv 값에 셸 명령이나 `${VARIABLE}` 확장을 수행하지 않습니다. 원격 URL은 HTTPS를 사용하며 로컬 개발용 loopback 주소만 HTTP를 허용합니다. URL의 인증 정보·쿼리·fragment는 허용하지 않습니다.
76
76
 
77
+ 프로젝트 밖에서도 상대 파일을 선택할 수 있습니다.
78
+
79
+ ```sh
80
+ steercards doctor --cwd /absolute/path/project --env-file alternate.env
81
+ npx -y -- @steercards/agent-tools@latest doctor --cwd /absolute/path/project --env-file alternate.env
82
+ ```
83
+
84
+ `npx`에서는 패키지 이름 앞의 `--`를 유지하세요. Node 22 일부 버전은 프로그램 뒤의 `--env-file`도 시작 전에 검사하므로 이 경계가 필요합니다. 직접 Node로 실행할 때도 위 예시처럼 스크립트 경로 앞에 `--`를 넣습니다. 설치된 `steercards`와 새로 생성한 MCP 설정은 이 경계를 포함합니다. 기존 MCP 설정은 업데이트 후 `setup`을 다시 실행해 갱신하세요. Windows에서는 Node 22·24에 포함된 npm의 CMD·PowerShell shim을 사용합니다.
85
+
77
86
  GUI 앱은 터미널과 다른 디렉터리·환경에서 시작될 수 있습니다. 설정을 생성할 때 `--cwd`에 실제 프로젝트의 절대 경로를 지정하세요. 여러 프로젝트를 사용하면 서버 이름과 `--cwd`를 프로젝트별로 구분하세요. 키는 MCP 설정에 복사하지 않고 해당 프로젝트의 `.env`에 둡니다.
78
87
 
79
88
  ## 클라이언트 설치·업데이트
@@ -180,11 +189,11 @@ Claude Code, Codex 앱·CLI, Cursor, Claude Desktop 각각의 네이티브 UI
180
189
  npm ci
181
190
  npm run check
182
191
  npm test
183
- npm run build
192
+ npm run test:package
184
193
  npm pack --dry-run
185
194
  ```
186
195
 
187
- CI는 Linux·macOS·Windows의 Node 22·24에서 같은 검사를 실행합니다. 테스트는 로컬 fixture를 사용하며 실제 Agent Key가 필요하지 않습니다. 기여 방법은 [CONTRIBUTING.md](CONTRIBUTING.md), 보안 보고는 [SECURITY.md](SECURITY.md)를 참고하세요.
196
+ CI는 Linux·macOS·Windows의 Node 22·24에서 같은 검사를 실행합니다. `test:package`는 빌드한 tarball을 별도 프로젝트에 설치하고 실제 bin·npx 및 생성된 MCP 명령을 실행합니다. Windows에서는 CMD와 PowerShell shim도 검사합니다. 의존성은 lockfile과 `npm ci`의 캐시를 재사용하며 실제 Agent Key가 필요하지 않습니다. 기여 방법은 [CONTRIBUTING.md](CONTRIBUTING.md), 보안 보고는 [SECURITY.md](SECURITY.md)를 참고하세요.
188
197
 
189
198
  공개 소스는 [velody-ai/steercards-agent-tools](https://github.com/velody-ai/steercards-agent-tools)에서 관리합니다. 안정 버전 GitHub Release를 게시하면 `publish.yml`이 태그·패키지 버전과 main 포함 여부를 확인하고 검사를 다시 실행한 뒤 npm에 게시합니다. 인증은 GitHub OIDC trusted publishing을 사용하며 공개 패키지에 provenance를 연결합니다.
190
199
 
package/dist/cli.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env -S node --
2
2
  export {};
package/dist/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env -S node --
2
2
  import { parseArgs } from 'node:util';
3
3
  import { readFile } from 'node:fs/promises';
4
4
  import { resolve } from 'node:path';
package/dist/install.d.ts CHANGED
@@ -1,9 +1,5 @@
1
- export declare const packageRoot: string;
1
+ export { packageRoot, packageInfo } from './package.js';
2
2
  export declare const skillRoot: string;
3
- export declare const packageInfo: {
4
- name: string;
5
- version: string;
6
- };
7
3
  export declare const clients: readonly ["claude-code", "codex", "codex-app", "codex-cli", "cursor", "claude-desktop"];
8
4
  export type Client = typeof clients[number];
9
5
  export declare function clientConfig(client: string, options?: {
package/dist/install.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import { readFile, readdir, mkdir, lstat, rename, rm, mkdtemp, writeFile } from 'node:fs/promises';
2
2
  import { dirname, join, resolve } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
- import { fileURLToPath } from 'node:url';
5
4
  import { zipSync } from 'fflate';
6
5
  import { validateMcpUrl } from './config.js';
7
- export const packageRoot = fileURLToPath(new URL('../', import.meta.url));
6
+ import { packageRoot, packageInfo } from './package.js';
7
+ export { packageRoot, packageInfo } from './package.js';
8
8
  export const skillRoot = join(packageRoot, 'skills', 'steercards');
9
- export const packageInfo = JSON.parse(await readFile(join(packageRoot, 'package.json'), 'utf8'));
10
9
  export const clients = ['claude-code', 'codex', 'codex-app', 'codex-cli', 'cursor', 'claude-desktop'];
11
10
  export function clientConfig(client, options = {}) {
12
11
  if (!clients.includes(client))
@@ -15,7 +14,9 @@ export function clientConfig(client, options = {}) {
15
14
  if (!['compact', 'full'].includes(mode))
16
15
  throw new Error('Mode must be compact or full.');
17
16
  const cwd = resolve(options.cwd ?? process.cwd());
18
- const args = options.local ? [join(packageRoot, 'dist', 'cli.js')] : ['-y', `${packageInfo.name}@${packageInfo.version}`];
17
+ // Node 22 pre-scans --env-file even after the script path. Protect both the
18
+ // local Node process and the outer npx process before passing CLI options.
19
+ const args = options.local ? ['--', join(packageRoot, 'dist', 'cli.js')] : ['-y', '--', `${packageInfo.name}@${packageInfo.version}`];
19
20
  args.push('serve', '--cwd', cwd, '--mode', mode);
20
21
  if (options.envFile)
21
22
  args.push('--env-file', resolve(cwd, options.envFile));
@@ -0,0 +1,5 @@
1
+ export declare const packageRoot: string;
2
+ export declare const packageInfo: {
3
+ name: string;
4
+ version: string;
5
+ };
@@ -0,0 +1,5 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { join } from 'node:path';
4
+ export const packageRoot = fileURLToPath(new URL('../', import.meta.url));
5
+ export const packageInfo = JSON.parse(await readFile(join(packageRoot, 'package.json'), 'utf8'));
package/dist/runtime.js CHANGED
@@ -2,6 +2,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
2
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
3
3
  import { CallToolResultSchema, ListToolsResultSchema, ToolListChangedNotificationSchema, } from '@modelcontextprotocol/sdk/types.js';
4
4
  import { validateMcpUrl } from './config.js';
5
+ import { packageInfo } from './package.js';
5
6
  /** Extract only a small, machine-readable code; arbitrary error prose stays private. */
6
7
  async function httpErrorCode(response, agentKey) {
7
8
  if (!response.headers.get('content-type')?.toLowerCase().includes('application/json') || !response.body) {
@@ -59,7 +60,7 @@ export class Runtime {
59
60
  return this.client;
60
61
  if (!this.connecting) {
61
62
  this.connecting = (async () => {
62
- const client = new Client({ name: '@steercards/agent-tools', version: '0.1.0' });
63
+ const client = new Client({ name: packageInfo.name, version: packageInfo.version });
63
64
  client.setNotificationHandler(ToolListChangedNotificationSchema, async () => { this.catalog = undefined; });
64
65
  const endpoint = this.config.url;
65
66
  const transport = new StreamableHTTPClientTransport(new URL(endpoint), {
package/dist/server.js CHANGED
@@ -2,6 +2,7 @@ import { readFile } from 'node:fs/promises';
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { CallToolRequestSchema, ErrorCode, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { packageInfo } from './package.js';
5
6
  const guideTopics = ['overview', 'discovery', 'cards', 'profiles', 'claims-runs', 'context', 'files', 'collaboration'];
6
7
  const guideUri = 'steercards://guide/';
7
8
  const instructions = 'Steercards tools use progressive discovery. In compact mode search tool metadata, describe the selected tool to obtain its current schema, then call it with matching arguments. Read the Steercards guide for workflows. Tool schemas are fetched from the authenticated upstream server. Respect isError and structuredContent. Never automatically retry a mutation after a network failure; read current state first. The upstream rate limit is 120 requests per minute; follow Retry-After.';
@@ -54,7 +55,7 @@ function assertKeys(args, keys) {
54
55
  export function createServer(runtime, { mode }) {
55
56
  if (mode !== 'compact' && mode !== 'full')
56
57
  throw new Error('Server mode must be compact or full.');
57
- const server = new Server({ name: '@steercards/agent-tools', version: '0.1.0' }, {
58
+ const server = new Server({ name: packageInfo.name, version: packageInfo.version }, {
58
59
  capabilities: { tools: {}, resources: {} }, instructions,
59
60
  });
60
61
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
package/docs/releases.md CHANGED
@@ -4,7 +4,14 @@
4
4
 
5
5
  ## 최초 설정
6
6
 
7
- 1. npm의 `steercards` 조직과 패키지 쓰기 권한을 확인합니다. 아직 존재하지 않는 패키지에는 일반 trusted publisher 설정을 추가할 수 없습니다. 첫 버전부터 GitHub Actions로 게시하려면 npm 11.15.0 이상에서 로그인하고 검증한 소스를 `npm stage publish --access public`로 준비합니다. [staged publishing](https://docs.npmjs.com/staged-publishing/)은 새 패키지에 공개 placeholder `0.0.0-stage`를 생성합니다. 실제 `0.1.0`은 승인 전까지 설치할 수 없습니다.
7
+ 1. npm의 `steercards` 조직과 패키지 쓰기 권한을 확인합니다. trusted publisher는 패키지가 레지스트리에 존재해야 설정할 수 있습니다. 최초 `0.1.0`은 검사한 tarball을 유지관리자의 npm 로그인·2FA로 일반 게시합니다.
8
+
9
+ ```sh
10
+ npm publish /absolute/path/steercards-agent-tools-0.1.0.tgz --access public --ignore-scripts
11
+ npm view @steercards/agent-tools@0.1.0 version dist.integrity
12
+ ```
13
+
14
+ 로컬 최초 게시에는 provenance가 없습니다. 다음 `0.1.1`은 아래 OIDC 절차로 게시하여 provenance를 확인합니다. 이미 게시한 버전은 덮어쓸 수 없습니다.
8
15
  2. GitHub 저장소의 Settings → Environments에 `npm` 환경을 만듭니다. 릴리스 권한을 가진 유지관리자만 릴리스 태그를 만들 수 있도록 저장소 ruleset과 환경 보호 규칙을 관리합니다.
9
16
  3. npm 패키지 Settings → Trusted Publisher에 아래 값을 등록합니다. 환경 이름까지 대소문자를 정확히 맞춥니다.
10
17
 
@@ -18,16 +25,16 @@
18
25
  | Allowed actions | `npm publish` 허용 |
19
26
 
20
27
  신규 설정은 staged publish만 기본 허용할 수 있으므로 직접 게시 권한을 명시적으로 켭니다. 워크플로는 장기 npm 토큰 없이 GitHub OIDC로 인증합니다. `NPM_TOKEN`·`NODE_AUTH_TOKEN` secret은 추가하지 않습니다.
21
- 4. placeholder로 시작했다면 npm staged packages 화면이나 `npm stage` 명령으로 준비한 `0.1.0`을 reject합니다. staged 버전 제거와 `npm view @steercards/agent-tools@0.1.0`의 미게시 상태를 확인한 뒤 아래 GitHub Release 절차를 진행합니다. 같은 버전의 staged → reject → OIDC 직접 게시 전환은 최초 설정에서 실제 레지스트리 상태로 확인해야 합니다. staged 버전을 먼저 approve하면 같은 버전을 Actions에서 다시 게시할 수 없습니다. 새 trusted publisher는 등록 후 2일 안에 첫 게시를 성공해야 검증되므로 실제 게시를 바로 이어갈 때 등록합니다. 토큰 게시를 제한하려면 OIDC 확인 후 npm 패키지의 Publishing access를 **Require two-factor authentication and disallow tokens**로 설정합니다.
28
+ 4. 새 trusted publisher는 등록 후 2일 안에 첫 게시를 성공해야 검증됩니다. 다음 버전 PR과 검사가 준비되어 실제 OIDC 게시를 바로 이어갈 때 등록합니다. OIDC 확인 후 npm 패키지의 Publishing access를 **Require two-factor authentication and disallow tokens**로 설정합니다.
22
29
 
23
30
  ## 새 버전 게시
24
31
 
25
- 1. 버전 변경은 별도 PR로 검토합니다. `npm version patch --no-git-tag-version`(또는 `minor`/`major`)으로 `package.json`과 `package-lock.json`의 버전을 함께 올리고 main에 병합합니다. 첫 게시 시 이미 선언된 `0.1.0`을 사용할 수 있습니다.
32
+ 1. 버전 변경은 별도 PR로 검토합니다. `npm version patch --no-git-tag-version`(또는 `minor`/`major`)으로 `package.json`과 `package-lock.json`의 버전을 함께 올리고 main에 병합합니다.
26
33
  2. README의 개발 검사를 실행하고 `npm pack --dry-run`의 포함 파일을 확인합니다. `.env`, 키, 테스트 데이터가 없어야 하며 `dist`, Skill, README, LICENSE가 포함되어야 합니다. 실제 tarball을 별도 디렉터리에 설치해 CLI와 `setup`도 확인합니다.
27
34
  3. 통과한 main 커밋을 대상으로 `v<package.json 버전>` 태그의 안정 버전 GitHub Release를 게시합니다. CLI 예시:
28
35
 
29
36
  ```sh
30
- gh release create v0.1.0 --repo velody-ai/steercards-agent-tools --target <검증한-main-커밋-SHA> --title v0.1.0 --generate-notes
37
+ gh release create v0.1.1 --repo velody-ai/steercards-agent-tools --target <검증한-main-커밋-SHA> --title v0.1.1 --generate-notes
31
38
  ```
32
39
 
33
40
  예시 버전과 SHA는 실제 릴리스에 맞춥니다. 초안 저장만으로는 게시하지 않으며 prerelease는 건너뜁니다. `latest` 외의 배포 태그는 현재 워크플로의 지원 범위에 없습니다.
@@ -38,6 +45,7 @@
38
45
 
39
46
  - OIDC 인증 오류: npm 설정의 저장소·workflow 파일명·`npm` 환경·직접 게시 권한을 확인합니다. GitHub-hosted runner와 npm 최소 버전도 확인합니다. 임시 해결용 토큰을 추가하지 않습니다.
40
47
  - 태그·버전 또는 main 포함 검사 실패: 릴리스가 가리키는 커밋과 버전 변경 PR을 확인합니다. 이미 게시된 npm 버전은 덮어쓰지 않습니다.
48
+ - staged 버전은 직접 게시와 같은 버전 공간을 사용합니다. `0.1.0`을 stage한 상태에서 같은 버전을 직접 게시하면 `E409`가 발생했습니다. 최초 placeholder만 있는 패키지에서 마지막 stage를 reject하자 패키지가 레지스트리에서 조회되지 않고 OIDC 재시도는 `E404`로 실패했습니다([실행 기록](https://github.com/velody-ai/steercards-agent-tools/actions/runs/39330030138)). trusted publisher 설정의 삭제 여부는 이 결과만으로 판단하지 않습니다. 초기 설정에 stage → reject 절차를 사용하지 않습니다. 일반 최초 게시 후 패키지와 기존 trusted publisher 설정을 확인하고 필요한 설정을 진행합니다.
41
49
  - 게시 후 후속 단계가 실패했다면 먼저 `npm view`로 게시 여부를 확인합니다. 미게시일 때만 실패한 Actions 작업을 재실행합니다. 이미 게시된 버전에 다시 `npm publish`하면 오류가 납니다.
42
50
 
43
51
  근거: [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/), [npm provenance](https://docs.npmjs.com/generating-provenance-statements/), [npm trust 전제 조건](https://docs.npmjs.com/cli/v11/commands/npm-trust/).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steercards/agent-tools",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Progressive MCP discovery, CLI and agent skills for Steercards",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,6 +28,7 @@
28
28
  "scripts": {
29
29
  "build": "tsc",
30
30
  "test": "node --import tsx --test test/*.test.ts",
31
+ "test:package": "npm run build && node --test test/package.test.mjs",
31
32
  "check": "tsc --noEmit",
32
33
  "prepack": "npm run build"
33
34
  },
@@ -14,6 +14,12 @@ Only one of `before`, `after`, `pageCursor`, `refreshKeys` is allowed per call.
14
14
 
15
15
  `request_human_check` names a real workspace member, prod/local environment and action/expected-result steps. It creates an item in the person's check inbox. Optional pass/fail business-status transitions must reflect the intended task. Query `list_human_checks` / `get_human_check` for actual verdicts and evidence. Creating the request is not a passed check, and "human check" is not a board status to invent.
16
16
 
17
+ Describe the live tool before constructing a request. Verification can optionally provide `resultOptions: [{id,label,description?,verdict}]`: 2–6 ordered choices shared by every step. IDs are unique ASCII letters/digits/underscore/hyphen (1–64 characters), labels are 1–120 characters and descriptions at most 500. Each verdict explicitly means `pass`, `fail` or `inconclusive`; never infer meaning from the label. Omit resultOptions to retain legacy pass/fail choices. Explicit null and mixing resultOptions with a question are invalid.
18
+
19
+ For example, use `works / Normal operation / pass`, `partial / Partly working / fail`, and `unable / Cannot verify / inconclusive`. Any failed step makes the result `failed`; otherwise any inconclusive step makes it `answered`; only all-pass becomes `passed`. A fail requires a memo. Inconclusive permits an optional memo and never means success. Verification `followUps` uses `onPassed`, `onFailed` and `onAnswered` once after aggregation. Omitted follow-ups keep the card state; inconclusive never falls back to legacy onFailStatus. For per-choice moves, use a single-selection question instead.
20
+
21
+ The assigned person chooses in the web inbox, saves each step, then explicitly submits the final response. Selection and step saving do not finalize the check or create the completion comment/webhook. Do not answer on the person's behalf. Read `steps[].selectedOptionId` and `selectedOptionSnapshot` for original ID, label, description and verdict; final `response` preserves resultOptions and steps. Processed history, comments and `human_check.completed` retain the original choice. Inspect actual `followUpResult` as current card state, permissions or workflow may block a requested move.
22
+
17
23
  `set_agent_status` / `clear_agent_status` expose working/input-wait/error. A waiting question can create a pinned agent comment; it is not equivalent to a step-by-step human check. Working status needs refresh at least every ten minutes. Check claim fences when the card is claim-managed.
18
24
 
19
25
  ## Reserve shared resources