@team-agent/installer 0.5.104 → 0.5.106

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.
Files changed (38) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/README.md +5 -3
  4. package/README.zh.md +4 -3
  5. package/crates/team-agent/src/cli/adapters.rs +17 -1
  6. package/crates/team-agent/src/cli/emit.rs +135 -18
  7. package/crates/team-agent/src/cli/mod.rs +156 -35
  8. package/crates/team-agent/src/cli/spec.rs +2 -2
  9. package/crates/team-agent/src/cli/status_port/brief.rs +62 -3
  10. package/crates/team-agent/src/cli/tests/run_delegation.rs +5 -2
  11. package/crates/team-agent/src/cli/tests/status_send.rs +2 -2
  12. package/crates/team-agent/src/cli/types.rs +3 -1
  13. package/crates/team-agent/src/lifecycle/launch/add_agent.rs +6 -2
  14. package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +6 -4
  15. package/crates/team-agent/src/lifecycle/launch/role_source.rs +1 -1
  16. package/crates/team-agent/src/lifecycle/launch/spec_state.rs +7 -2
  17. package/crates/team-agent/src/lifecycle/launch/state_projection.rs +8 -3
  18. package/crates/team-agent/src/lifecycle/launch.rs +4 -1
  19. package/crates/team-agent/src/lifecycle/mod.rs +1 -0
  20. package/crates/team-agent/src/lifecycle/restart/agent.rs +75 -0
  21. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +24 -17
  22. package/crates/team-agent/src/lifecycle/restart.rs +1 -1
  23. package/crates/team-agent/src/lifecycle/role_config.rs +1123 -0
  24. package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +22 -0
  25. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +43 -0
  26. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +71 -0
  27. package/crates/team-agent/src/lifecycle/tests/restart_build_before_destroy_0540_contract.rs +6 -2
  28. package/crates/team-agent/src/state/projection.rs +15 -0
  29. package/crates/team-agent/src/state/repository.rs +2 -1
  30. package/crates/team-agent/src/tmux_backend/tests.rs +137 -0
  31. package/crates/team-agent/src/tmux_backend.rs +110 -0
  32. package/crates/team-agent/src/transport/test_support.rs +35 -0
  33. package/crates/team-agent/src/transport/tests/wire.rs +32 -3
  34. package/crates/team-agent/src/transport.rs +26 -12
  35. package/package.json +4 -4
  36. package/skills/team-agent/SKILL.md +55 -20
  37. package/skills/team-agent/references/recovery-runbook.md +2 -2
  38. package/skills/team-agent/references/team-agent-operator.md +14 -6
@@ -366,16 +366,45 @@ fn inject_empty_payload_reports_empty_text_send_keys_and_turn_not_required() {
366
366
  assert_eq!(report.attempts, 1);
367
367
  }
368
368
 
369
+ #[cfg(unix)]
370
+ #[test]
371
+ #[ignore = "requires native tmux 3.5+ and python3; owns an isolated socket/session"]
372
+ fn submit_key_protocol_native_tmux_is_return_in_legacy_and_extended_modes() {
373
+ let fixture = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
374
+ .join("tests/fixtures/submit_key_protocol_probe.py");
375
+ let output = std::process::Command::new("python3")
376
+ .arg(fixture)
377
+ .args([
378
+ "--submit-key",
379
+ crate::transport::tmux_submit_key_name(Key::Enter),
380
+ ])
381
+ .output()
382
+ .expect("run isolated raw-PTY submit diagnostic");
383
+ assert!(
384
+ output.status.success(),
385
+ "production submit key is not Return: stdout={} stderr={}",
386
+ String::from_utf8_lossy(&output.stdout),
387
+ String::from_utf8_lossy(&output.stderr),
388
+ );
389
+ assert!(String::from_utf8_lossy(&output.stdout)
390
+ .contains("ProductionSubmitReturn=verified-three-modes"));
391
+ }
392
+
369
393
  #[test]
370
394
  fn empty_inject_is_single_direct_send_keys_never_buffer() {
371
395
  // 命令构造 golden(STEP-9):空文本禁走 buffer,只发一条 send-keys 提交键
372
396
  // (tmux_io.py:42 —— tmux 拒空 buffer 会卡 trust prompt)。
373
- // golden empty_inject_calls 仅 1 条:send-keys -t %7 C-m(锁定阳性 CR)。
397
+ // Return 与 Ctrl-M 只在 legacy 模式等价;提交必须保持逻辑 Enter。
374
398
  assert_eq!(
375
399
  tmux_empty_inject_argv(&PaneId::new("%7"), Key::Enter),
376
- vec!["tmux", "send-keys", "-t", "%7", "C-m"]
400
+ vec!["tmux", "send-keys", "-t", "%7", "Enter"]
401
+ );
402
+ assert_eq!(
403
+ crate::transport::tmux_send_submit_argv(&PaneId::new("%7"), Key::Enter),
404
+ vec!["tmux", "send-keys", "-t", "%7", "Enter"]
377
405
  );
378
- assert_eq!(crate::transport::tmux_submit_key_name(Key::Enter), "C-m");
406
+ assert_eq!(crate::transport::tmux_submit_key_name(Key::Enter), "Enter");
407
+ assert_eq!(crate::transport::tmux_submit_key_name(Key::Down), "Down");
379
408
  }
380
409
 
381
410
  #[test]
@@ -13,7 +13,7 @@
13
13
  //! - name: tmux_inject_text_argv
14
14
  //! what: 文本注入三步 argv(装 buffer→paste→删 buffer)的唯一构造点
15
15
  //! - name: tmux_send_submit_argv
16
- //! what: 提交键 argv 的唯一构造点,Enter 锁定为 C-m
16
+ //! what: 提交键 argv 的唯一构造点,Enter 保持逻辑 Return 而非 Ctrl-M
17
17
  //! - name: tmux_capture_argv
18
18
  //! what: capture-pane argv 的唯一构造点
19
19
  //! - name: tmux_query_argv
@@ -994,6 +994,12 @@ pub trait Transport: Send + Sync {
994
994
  Ok(None)
995
995
  }
996
996
 
997
+ /// Native dead-pane observation. Only Some(true) proves no live pane
998
+ /// process; a missing/unsupported sample must remain unknown.
999
+ fn pane_is_dead(&self, _pane: &PaneId) -> Result<Option<bool>, TransportError> {
1000
+ Ok(None)
1001
+ }
1002
+
997
1003
  /// Cheap direct pane existence check when a backend can prove it. `Ok(None)`
998
1004
  /// preserves the existing Unknown boundary.
999
1005
  fn has_pane(&self, pane: &PaneId) -> Result<Option<bool>, TransportError> {
@@ -1085,6 +1091,17 @@ pub trait Transport: Send + Sync {
1085
1091
 
1086
1092
  // —— LIFECYCLE(SL)——
1087
1093
 
1094
+ /// Before stopping a seat, preserve its session if removing these targets
1095
+ /// would otherwise destroy it. This is not called by team shutdown/restart.
1096
+ /// Backends whose sessions outlive their panes need no special handling.
1097
+ fn preserve_session_before_stop(
1098
+ &self,
1099
+ _session: &SessionName,
1100
+ _targets: &[Target],
1101
+ ) -> Result<(), TransportError> {
1102
+ Ok(())
1103
+ }
1104
+
1088
1105
  fn kill_server(&self) -> Result<(), TransportError> {
1089
1106
  Ok(())
1090
1107
  }
@@ -1199,21 +1216,18 @@ pub fn tmux_send_keys_argv(pane: &PaneId, keys: &[Key]) -> Vec<String> {
1199
1216
 
1200
1217
  /// 投递提交键的 tmux 拼写。
1201
1218
  ///
1202
- /// ledger.p0enter 锁定对:`C-j`/LF 5/5 不成回合,`C-m`/CR 5/5 成回合。
1203
- /// `send-keys Enter` 在 raw PTY 上也是 `0d`,但提交路径只发锁定阳性名
1204
- /// `C-m`,避免落到 LF 族。菜单 `send_keys([Down, Enter])` 不走这里。
1219
+ /// `Enter` 必须保持逻辑 Return,不能替换成控制组合 `C-m`。
1220
+ /// legacy PTY 中两者都是 CR,但启用 extended keys 后 `C-m` 会成为
1221
+ /// CSI-u / modifyOtherKeys Ctrl-M,Pi 不把它当提交;`Enter` 仍发送 CR。
1205
1222
  /// ---
1206
- /// purpose: 投递提交键的 tmux 拼写:Enter 锁定为 C-m(CR),其余键回落通用翻译
1223
+ /// purpose: 投递提交键复用通用逻辑键翻译,避免协议相关的控制键别名
1207
1224
  /// params:
1208
- /// key: 提交键;只有 Enter 有专门拼写
1209
- /// returns: 提交用键名;非 Enter 与 tmux_key_name 同值(含空串情形)
1225
+ /// key: 逻辑提交键
1226
+ /// returns: 与 tmux_key_name 同值(含空串情形)
1210
1227
  /// boundary: 只管拼写,不管何时提交、提交是否成功;不发送、不验证
1211
1228
  /// ---
1212
1229
  pub fn tmux_submit_key_name(key: Key) -> &'static str {
1213
- match key {
1214
- Key::Enter => "C-m",
1215
- other => tmux_key_name(other),
1216
- }
1230
+ tmux_key_name(key)
1217
1231
  }
1218
1232
 
1219
1233
  /// 投递提交:`send-keys -t <pane> <submit-spelling>`。
@@ -1478,7 +1492,7 @@ pub fn tmux_inject_text_argv(
1478
1492
 
1479
1493
  /// 空文本 inject:纯 `send-keys -t <target> <submit_key>`,**禁** buffer 路径
1480
1494
  /// (tmux 拒空 buffer 会卡 trust prompt;tmux_io.py:42)。
1481
- /// `Key::Enter` 在此译成锁定阳性 `C-m`,不是菜单用的 `Enter`。
1495
+ /// `Key::Enter` 保持逻辑 `Enter`,不会在 extended keys 下误发 Ctrl-M。
1482
1496
  /// ---
1483
1497
  /// purpose: 空载荷注入(唤醒/ping)的 argv:只发提交键,不碰 buffer
1484
1498
  /// params:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-agent/installer",
3
- "version": "0.5.104",
3
+ "version": "0.5.106",
4
4
  "description": "npx installer for Team Agent",
5
5
  "keywords": [
6
6
  "codex",
@@ -20,9 +20,9 @@
20
20
  "team-agent-installer": "npm/install.mjs"
21
21
  },
22
22
  "optionalDependencies": {
23
- "@team-agent/cli-darwin-arm64": "0.5.104",
24
- "@team-agent/cli-darwin-x64": "0.5.104",
25
- "@team-agent/cli-linux-x64": "0.5.104"
23
+ "@team-agent/cli-darwin-arm64": "0.5.106",
24
+ "@team-agent/cli-darwin-x64": "0.5.106",
25
+ "@team-agent/cli-linux-x64": "0.5.106"
26
26
  },
27
27
  "scripts": {
28
28
  "postinstall": "node npm/bincheck.mjs",
@@ -7,48 +7,83 @@ requires_team_agent: ">=0.5.0"
7
7
 
8
8
  The current assistant is the **leader**. Workers use separate role files and report through Team Agent. Start from a tmux-addressable terminal or supported agent pane, in the workspace root (the parent of the team directory).
9
9
 
10
+ ## Decide before creating a team
11
+
12
+ **The user decides each worker's provider and permission bypass. Do not silently choose Pi, true, or false.** Reuse an explicit user policy when it covers the worker; otherwise explain the choices and ask before starting.
13
+
14
+ Use existing resources rather than establishing new accounts: `team-agent doctor --workspace . --json` reports discovered tools, but installed does not mean authenticated and an absent entry or unknown auth is not proof of unavailability. For providers supported by `models`, use `team-agent models --provider NAME` to check exact model IDs. Do not inspect credentials, automatically log in, or silently substitute a provider after a failed probe.
15
+
16
+ | Choice | What to explain |
17
+ |---|---|
18
+ | Pi | One Agent tool can use several model catalogs; explicit models require a qualified ID such as `openai-codex/gpt-6-luna` |
19
+ | Codex | The user's existing Codex workflow, native tools, permissions and resumable sessions |
20
+ | Claude / Claude Code | The user's existing Claude workflow, models, native tools and session behavior |
21
+ | Bypass `true` | Fewer permission interruptions, but broader automatic execution authority |
22
+ | Bypass `false` | Keep the selected tool's native permissions; human confirmation may interrupt unattended work |
23
+
24
+ False is **not** a read-only or sandbox guarantee. Native permission capabilities differ between tools. Suggest combinations based on the user's installed tools, subscriptions and task: for example, an explicitly chosen Codex implementer and Claude reviewer, or two Pi workers when those are the available resources. Different workers may use different providers; an existing worker cannot change provider.
25
+
10
26
  ## Create and start
11
27
 
12
- A team can be plain text; no YAML frontmatter is required:
28
+ Keep the goal in `TEAM.md` and each worker's instructions in `agents/*.md`. The filename stem is the worker's in-team short name.
13
29
 
14
30
  ```text
15
31
  .team/current/
16
- TEAM.md # the team's goal
17
- agents/reviewer.md # the worker's instructions
32
+ TEAM.md
33
+ agents/reviewer.md
18
34
  ```
19
35
 
20
- Put the goal in `TEAM.md` and the worker's instructions in each `agents/*.md` body. Use the filename stem as the worker id and in-team short name in commands such as `send` and `inbox`.
36
+ For a **new plan**, record the user's two decisions in every role. This example assumes the user selected Pi and bypass false; it is not a default:
37
+
38
+ ```markdown
39
+ ---
40
+ provider: pi
41
+ dangerously_skip_permissions: false
42
+ ---
43
+ Review the change and report concrete regression risks.
44
+ ```
21
45
 
22
46
  ```sh
23
47
  team-agent quick-start .team/current
24
48
  team-agent send reviewer "Review this change"
25
49
  team-agent inbox reviewer -n 3
26
- team-agent add-agent analyst --role-file /absolute/path/to/analyst.md
27
- team-agent shutdown --workspace .
28
50
  ```
29
51
 
30
- The `reviewer` argument is an in-team short name; use `<workspace>::<team>/<agent>` when the recipient needs a fully qualified identity. A successful `send` may mean only queued; it is not the worker's reply. Wait for a natural response or result before treating the task as complete.
52
+ Traditional file-based quick-start/compile behavior remains supported, including legacy minimal role documents; no conversion to CLI-created roles is required. Legacy interpretation is not permission to silently choose settings for a new user plan. Model and effort may remain unset; preserve the existing file compiler's native/default interpretation rather than inventing a model or effort.
31
53
 
32
- ## Role defaults
54
+ To add a **new** seat to an existing team, provider and bypass must be explicitly defined in the CLI or role file. A complete traditional role file needs no repeated flags. If both sources define a field, equal values are accepted and **conflicting values are rejected before any write or startup**:
33
55
 
34
- All role metadata is optional. With no overrides:
56
+ ```sh
57
+ # These values must be the user's choices, not inferred defaults.
58
+ team-agent add-agent analyst --provider pi --bypass true --prompt "Analyze the proposed change"
59
+ # auditor.md already contains the user's provider and bypass decisions.
60
+ team-agent add-agent auditor --role-file /absolute/path/to/auditor.md
61
+ ```
35
62
 
36
- | Setting | Default |
37
- |---|---|
38
- | Provider | `pi` |
39
- | Model | unset; let the provider choose |
40
- | Effort | unset; let the provider choose |
41
- | Permission bypass | `false`; keep provider-native permissions |
63
+ Add creates and immediately starts the seat. Ordinary add rejects an occupied ID, including stopped seats. Disaster recovery has one explicit exception: `add-agent ID --role-file FILE --force` may reuse the existing force-recreate lifecycle only when the registered old pane is positively confirmed dead and no live target cohort exists. A live seat or unknown/missing death proof is refused; force is not a routine configuration-update shortcut. External role files are imported into the team's `agents/ID.md` and left untouched. A file already at that path is used in place, without copying itself.
64
+
65
+ ## Change and start an existing worker
66
+
67
+ **Stop first if it is running.** Start never implicitly kills or restarts a running worker:
68
+
69
+ ```sh
70
+ team-agent stop-agent reviewer
71
+ team-agent start-agent reviewer --effort high --bypass true
72
+ team-agent stop-agent reviewer
73
+ team-agent start-agent reviewer --prompt "Review only regression risks; do not change product code"
74
+ ```
75
+
76
+ Start updates the same role file and recompiles it before normal startup. Omitted options preserve the file's values and body; `--prompt` replaces the permanent role body, not a one-time task message. `--bypass true` and `--bypass false` are explicit values, not bare switches. Model, effort and an existing profile can also be set. Direct file edits followed by start use the same reload path.
42
77
 
43
- Add frontmatter only when a role needs an override. Supported fields include `agent_id` (legacy alias: `name`), `role`, `provider`, `model`, `effort`, `auth_mode`, `profile`, `dangerously_skip_permissions`, and `communication_mode`. Old `tools`, `permission_mode`, and `label` role keys do not configure a worker.
78
+ A different `--provider`, including a manually edited role provider, is rejected before launch. A matching provider is allowed. Create a separate ID to use a different engine. If startup fails, the role file and runtime spec are restored to their pre-command contents; the command reports failure, not an applied update.
44
79
 
45
- Profiles keep provider authentication, endpoint, and custom-model settings local. Never put secrets in `TEAM.md` or a role file. See [the operator reference](references/team-agent-operator.md) for profile setup and field details.
80
+ Profiles keep provider authentication, endpoints and custom-model settings local. Imported roles use this team's/workspace's `profiles`, never the original external directory. Prepare a named profile locally through the public profile commands; do not search for or copy external credentials. Never put secrets in `TEAM.md` or a role file. See [the operator reference](references/team-agent-operator.md) for existing profile and field details. Supported metadata also includes `agent_id` (legacy `name`), `role`, `auth_mode`, and `communication_mode`; old `tools`, `permission_mode`, and `label` keys do not configure a worker.
46
81
 
47
- ## Inspect
82
+ ## Inspect and stop
48
83
 
49
- Use `team-agent status --json` for readiness and `team-agent --help` for current command syntax. `ok: true` with `ready: false` means the command succeeded but the team is not ready; follow the reported action.
84
+ Use `team-agent status --json` for readiness and the installed command's `--help` for syntax. `ok: true` with `ready: false` means the team is not ready; follow the reported action. Accepted/queued send is not the worker's reply: wait for a natural response or result. Use `<workspace>::<team>/<agent>` when a fully qualified recipient is needed.
50
85
 
51
- Worker MCP provides `send_message`, `report_result`, and `get_team_status`. Lifecycle actions remain on the authorized CLI. See [nested teams](references/team-in-team.md) only when the task needs them.
86
+ Worker MCP provides `send_message`, `report_result`, and `get_team_status`. Lifecycle actions remain on the authorized CLI. See [nested teams](references/team-in-team.md) only when needed. Stop the selected team with `team-agent shutdown --workspace .` when authorized.
52
87
 
53
88
  ---
54
89
  This skill is a concise public guide. Do not infer a tested version from package metadata; verify the installed CLI with `team-agent --version` when version-specific behavior matters.
@@ -54,7 +54,7 @@ Diagnosis:
54
54
 
55
55
  ```bash
56
56
  team-agent status --workspace "$WORKSPACE" --json --detail
57
- team-agent collect --workspace "$WORKSPACE" --json
57
+ team-agent inbox "$AGENT_ID" --workspace "$WORKSPACE" --team "$TEAM" -n 3 --json
58
58
  ```
59
59
 
60
60
  What to look for:
@@ -167,7 +167,7 @@ Validate:
167
167
 
168
168
  ```bash
169
169
  team-agent status --workspace "$WORKSPACE" --json --detail
170
- team-agent collect --workspace "$WORKSPACE" --json
170
+ team-agent inbox "$AGENT_ID" --workspace "$WORKSPACE" --team "$TEAM" -n 3 --json
171
171
  ```
172
172
 
173
173
  The expected result is `status="restarted"` or an equivalent running projection without duplicate-session errors. Do not treat a partial failure on one worker as permission to reset the whole team.
@@ -20,15 +20,16 @@ From a tmux-addressable terminal or supported agent pane, run commands in the wo
20
20
  team-agent quick-start my-team
21
21
  team-agent send reviewer "Review the current change and report the main risk."
22
22
  team-agent inbox reviewer -n 3
23
+ # The role file already records the user's provider and bypass choices.
23
24
  team-agent add-agent analyst --role-file /absolute/path/to/analyst.md
24
25
  team-agent shutdown --workspace .
25
26
  ```
26
27
 
27
28
  A successful `send` can mean only accepted or queued. Wait for the worker's actual reply/result; acceptance is not completion. Use `team-agent status --json` to inspect readiness. `ok: true` with `ready: false` means the command succeeded but the team is not ready; follow the reported action.
28
29
 
29
- ## Defaults and optional role fields
30
+ ## User decisions and legacy compatibility
30
31
 
31
- No role frontmatter is required. With no explicit overrides, Team Agent uses:
32
+ For a new team plan, explicitly record each user's provider and bypass decisions; do not silently select either. Existing file-based compilation remains compatible, including minimal documents. The following table describes legacy interpretation, not defaults to choose on the user's behalf:
32
33
 
33
34
  | Setting | Default behavior |
34
35
  |---|---|
@@ -37,21 +38,27 @@ No role frontmatter is required. With no explicit overrides, Team Agent uses:
37
38
  | `effort` | Unset by Team Agent; leave effort selection to the provider |
38
39
  | `dangerously_skip_permissions` | `false`; preserve native permissions |
39
40
 
40
- Do not write `model: null`, `effort: max`, or a bypass setting just to restate a default. The absence of a model or effort override is not a promise about what the provider's own UI eventually displays. Team Agent does not fill role model from TEAM-level defaults. An unspecified role effort defaults to None (native); for non-Pi roles, a legacy explicit TEAM provider_effort remains supported for compatibility.
41
+ Do not invent `model: null` or `effort: max`. Record the user's bypass decision explicitly in a new role, even when it is false. The absence of a model or effort override is not a promise about what the provider's own UI eventually displays. Team Agent does not fill role model from TEAM-level defaults. An unspecified role effort defaults to None (native); for non-Pi roles, a legacy explicit TEAM provider_effort remains supported for compatibility.
41
42
 
42
43
  Optional supported role metadata:
43
44
 
44
45
  - `agent_id` (or legacy `name`) and `role` for identity.
45
46
  - `provider`, `model`, and `effort` to explicitly choose supported provider settings.
46
47
  - `auth_mode` and `profile` to use a provider profile.
47
- - `dangerously_skip_permissions: true` only when the user explicitly wants the provider-supported bypass behavior. The default is false.
48
+ - `dangerously_skip_permissions: true` or `false` records the user's explicit permission choice. False preserves native permissions; it is not a read-only or sandbox guarantee.
48
49
  - `communication_mode` to select a supported worker communication contract.
49
50
 
50
51
  Unknown and historical role keys are ignored, not used as a way to restrict tools or permissions. In particular, `tools`, `permission_mode`, and `label` do not configure a worker through role frontmatter.
51
52
 
53
+ ## Add and start
54
+
55
+ `add-agent ID --provider NAME --bypass true|false` creates and starts a new seat without a prepared file. A traditional `add-agent ID --role-file FILE` needs no repeated flags when the file already defines provider and boolean bypass. Missing decisions may be supplied by CLI; equal file/CLI values are accepted, but conflicting definitions (including model, effort, prompt and profile) are rejected before writing or startup. Model, effort, prompt and profile remain optional. External role-file inputs are imported into the selected team's `agents/ID.md`; the original stays untouched. A file already there is used in place. Ordinary add rejects occupied IDs. Explicit `--force` is restricted to disaster recovery: the registered old pane must be positively confirmed dead and the target must have no live cohort. Live or unknown targets remain refused; the existing force-recreate transaction is reused, not a general update/implicit-restart path.
56
+
57
+ `start-agent ID` starts an existing stopped seat; it refuses a running seat, so use `stop-agent ID` first. Optional model, effort, bypass, prompt and profile update that same role document. Omitted fields and body are preserved; prompt replaces the body. A matching provider is allowed; any engine change, including manual file edits, is refused. Startup failure restores role and runtime spec bytes, and reports failure. File edits followed by start use the same compiler reload path.
58
+
52
59
  ## Profiles and custom models
53
60
 
54
- A profile keeps provider credentials, endpoint settings, and optional model settings outside role text. This supports subscription profiles and custom/third-party API models, including Claude Code-compatible providers.
61
+ A profile keeps provider credentials, endpoint settings, and optional model settings outside role text. This supports subscription profiles and custom/third-party API models, including Claude Code-compatible providers. Once an external role is imported, profile lookup uses the current team's/workspace's `profiles`, not the external source directory. Prepare the profile locally through public commands; do not discover or copy external credentials.
55
62
 
56
63
  Create a local profile, then edit its generated file on the user's machine:
57
64
 
@@ -64,6 +71,7 @@ Reference it without copying secrets into Markdown:
64
71
  ```yaml
65
72
  ---
66
73
  provider: claude_code
74
+ dangerously_skip_permissions: false
67
75
  auth_mode: compatible_api
68
76
  profile: my-api
69
77
  ---
@@ -76,4 +84,4 @@ The profile can supply its model when the role has no explicit `model`; an expli
76
84
 
77
85
  Use `team-agent --help` or a command's `--help` for the installed CLI syntax. Worker MCP exposes `send_message`, `report_result`, and `get_team_status`; workers use `report_result` to return completion. Nested-team guidance is in [team-in-team.md](team-in-team.md).
78
86
 
79
- Keep role instructions in Markdown. Add metadata only for an intentional override; do not copy internal state fields or old frontmatter templates into new roles.
87
+ Keep role instructions in Markdown. Record explicit provider/bypass decisions for new plans, and add other metadata only for intentional settings; do not copy internal state fields into roles.