@humain/humain-code 0.3.8 → 0.4.1

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 (87) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/bundle/agent-monitor.js +1 -1
  3. package/dist/bundle/chunks/bedrock-converse-stream.js +45 -39
  4. package/dist/bundle/chunks/{chunk-REZ7FW4X.js → chunk-2KKLZK2N.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-3ZYKCI45.js → chunk-3ZI2TEVB.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-WQN4VIAM.js → chunk-7LDXR4AN.js} +424 -378
  7. package/dist/bundle/chunks/{chunk-YEG6NREY.js → chunk-DUZY4PDA.js} +16 -16
  8. package/dist/bundle/chunks/{chunk-QJZ5QYKE.js → chunk-E22S6D55.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-74L7EWMA.js → chunk-E7WGCXWK.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-MNB52OYZ.js → chunk-ERT2BD7V.js} +36 -36
  11. package/dist/bundle/chunks/{chunk-2KVH67UZ.js → chunk-H5CZL7M5.js} +1 -1
  12. package/dist/bundle/chunks/{chunk-TEOX3AWC.js → chunk-ICLZNV4V.js} +2 -2
  13. package/dist/bundle/chunks/{chunk-VHVY22A2.js → chunk-JQZ7BIAI.js} +2 -13
  14. package/dist/bundle/chunks/{chunk-HL54JCNV.js → chunk-KMMH6Z2Y.js} +3 -3
  15. package/dist/bundle/chunks/{chunk-6HQRNHO7.js → chunk-N23FFKJU.js} +40 -25
  16. package/dist/bundle/chunks/{chunk-X5JUC5RE.js → chunk-OXJXKCLB.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-QWB2GGVH.js → chunk-OYDXJK4L.js} +731 -736
  18. package/dist/bundle/chunks/{chunk-7CYWKPFS.js → chunk-UBQSONVR.js} +9 -8
  19. package/dist/bundle/chunks/{chunk-6MMGBL46.js → chunk-VZV7GLZT.js} +2 -2
  20. package/dist/bundle/chunks/{chunk-FF26YENK.js → chunk-W2QRCQBX.js} +4 -3
  21. package/dist/bundle/chunks/{cli-5NYUGRWC.js → cli-5YRA5PFB.js} +2 -2
  22. package/dist/bundle/chunks/{compat-UPJNJCGF.js → compat-GXD2ZGMZ.js} +1 -1
  23. package/dist/bundle/chunks/dist-IKSCGVMG.js +1953 -0
  24. package/dist/bundle/chunks/{easter-egg-3d-XUJ4HNAR.js → easter-egg-3d-ARXMB2RN.js} +1 -1
  25. package/dist/bundle/chunks/{esm-763X2IA7.js → esm-NCUV2DF7.js} +1 -1
  26. package/dist/bundle/chunks/{event-streams-4Q22QRY2.js → event-streams-CGCQQL5M.js} +1 -1
  27. package/dist/bundle/chunks/{execute-IAU7EI3P.js → execute-KEUC5IWA.js} +1 -1
  28. package/dist/bundle/chunks/{extract-QIC545HI.js → extract-WUAT5T4V.js} +4 -4
  29. package/dist/bundle/chunks/{google-generative-ai-ICWD4YIE.js → google-generative-ai-MDUVUFFQ.js} +1 -1
  30. package/dist/bundle/chunks/{google-vertex-XIACVW6H.js → google-vertex-UQGG6LEW.js} +1 -1
  31. package/dist/bundle/chunks/{host-QBIXSMNN.js → host-SPBJ4YAA.js} +1 -1
  32. package/dist/bundle/chunks/{node-W47VUEGE.js → node-XGNY74WT.js} +1 -1
  33. package/dist/bundle/chunks/{runtime-NBGMTCI6.js → runtime-HBWXEJT3.js} +1 -1
  34. package/dist/bundle/chunks/{virtual-modules-P2MH665T.js → virtual-modules-BYOLP3HY.js} +2 -2
  35. package/dist/bundle/cli-runtime.js +2 -2
  36. package/dist/bundle/flow/agents/.gitkeep +0 -0
  37. package/dist/bundle/flow/agents/orch-architect.md +33 -0
  38. package/dist/bundle/flow/agents/orch-implementation-fast.md +13 -0
  39. package/dist/bundle/flow/agents/orch-implementation-strong.md +28 -0
  40. package/dist/bundle/flow/agents/orch-qa-agent.md +29 -0
  41. package/dist/bundle/flow/agents/orch-scout.md +35 -0
  42. package/dist/bundle/flow/agents/orch-security-review.md +28 -0
  43. package/dist/bundle/flow/agents/orch-technical-lead.md +37 -0
  44. package/dist/bundle/flow/agents/orch-technical-review.md +28 -0
  45. package/dist/bundle/flow/agents/orch-worker.md +13 -0
  46. package/dist/bundle/flow/agents/orchestrator-lead.md +55 -0
  47. package/dist/bundle/flow/assets/.gitkeep +0 -0
  48. package/dist/bundle/flow/assets/contract.json +84 -0
  49. package/dist/bundle/flow/assets/forge-protocol-schema.sha256 +1 -0
  50. package/dist/bundle/flow/assets/method.json +193 -0
  51. package/dist/bundle/flow/assets/orchestrator-profiles.json +131 -0
  52. package/dist/bundle/flow/assets/profiles/anthropic.json +189 -0
  53. package/dist/bundle/flow/assets/profiles/openai.json +177 -0
  54. package/dist/bundle/flow/assets/profiles/oss-first.json +236 -0
  55. package/dist/bundle/flow/assets/profiles/premium.json +203 -0
  56. package/dist/bundle/flow/package.json +48 -0
  57. package/dist/bundle/index.js +5 -5
  58. package/dist/bundle/rpc-entry.js +2 -2
  59. package/dist/config.d.ts +12 -0
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/config.js +21 -0
  62. package/dist/config.js.map +1 -1
  63. package/dist/core/tools/subagent.d.ts +20 -0
  64. package/dist/core/tools/subagent.d.ts.map +1 -1
  65. package/dist/core/tools/subagent.js +124 -12
  66. package/dist/core/tools/subagent.js.map +1 -1
  67. package/dist/humain/flow-loader.d.ts +62 -0
  68. package/dist/humain/flow-loader.d.ts.map +1 -0
  69. package/dist/humain/flow-loader.js +291 -0
  70. package/dist/humain/flow-loader.js.map +1 -0
  71. package/dist/humain/index.d.ts.map +1 -1
  72. package/dist/humain/index.js +2 -0
  73. package/dist/humain/index.js.map +1 -1
  74. package/dist/humain/trace-capture/child-launch.d.ts +1 -0
  75. package/dist/humain/trace-capture/child-launch.d.ts.map +1 -1
  76. package/dist/humain/trace-capture/child-launch.js +2 -1
  77. package/dist/humain/trace-capture/child-launch.js.map +1 -1
  78. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  79. package/dist/modes/rpc/rpc-mode.js +136 -1
  80. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  81. package/docs/docs.json +8 -0
  82. package/docs/environment-variables.md +1 -0
  83. package/docs/flow-profiles.md +173 -0
  84. package/docs/flow.md +112 -0
  85. package/docs/index.md +2 -0
  86. package/npm-shrinkwrap.json +6 -6
  87. package/package.json +6 -5
@@ -0,0 +1,173 @@
1
+ # Flow Profiles
2
+
3
+ A Flow profile selects the models, limits, and spend cap for a HUMAIN Code Flow run. Profiles are implemented in `packages/flow/src/profiles/` and validated by the `FlowProfileV1` contract in `@humain/humain-code-contracts/flow-profile`.
4
+
5
+ ## What a profile is
6
+
7
+ A profile is one JSON document with `schema: "humain-flow-profile"` and `schemaVersion: 1`.
8
+
9
+ | Field | Meaning |
10
+ | --- | --- |
11
+ | `id` | Pattern `^[a-z0-9][a-z0-9_.:-]{0,127}$`. Also the file name. |
12
+ | `version` | Positive integer. Increases on every save. |
13
+ | `digest` | sha256 hex of the canonical JSON of the document without the `digest` field. |
14
+ | `kind` | `direct` or `flow`. |
15
+ | `label`, `description` | Display text. `label` is 1 to 80 characters, `description` at most 500. |
16
+ | `direct` | Only for `kind: direct`. A `model` and up to 8 `fallbacks`. |
17
+ | `roles` | Only for `kind: flow`. Maps a role to `{ primary, backups (max 8), effort: low\|medium\|high }`. |
18
+ | `sizing` | Optional, `kind: flow` only. Classifier policy id, `mediumAt` and `largeAt` thresholds, `triageRole`, `maxEscalations` (0 or 1). |
19
+ | `limits` | `maxAgents` 1..256, `maxConcurrent` 1..64, `maxDepth` 0..3, `maxRetries` 0..16, `inactivityMs` 1..86400000, `ciWaitMs` 0..86400000. |
20
+ | `spend` | `runCapMicrousd`, `warnAtPct` 1..99, optional `perRoleCapMicrousd`. |
21
+ | `providers` | Optional `preference` list of provider ids (max 16). |
22
+ | `approval`, `builtIn` | `builtIn: true` marks the shipped profiles. User profiles must not set it. |
23
+
24
+ Role names: `scout`, `worker`, `implementer`, `lead`, `lead_large`, `architect`, `reviewer`, `security_reviewer`, `qa`, `triage`.
25
+
26
+ Validation rules:
27
+
28
+ - `kind: direct` requires `direct` and forbids `roles` and `sizing`.
29
+ - `kind: flow` requires `roles.lead`, `roles.worker`, `roles.reviewer`, and `roles.qa`, and forbids `direct`.
30
+ - A model reference may not appear twice in one primary-plus-backups (or model-plus-fallbacks) list.
31
+ - `sizing.thresholds.mediumAt` must be at most `largeAt`.
32
+ - A profile file whose `digest` does not match its content is rejected.
33
+
34
+ ## Built-in profiles
35
+
36
+ Four read-only profiles ship in `packages/flow/assets/profiles/`. All are `kind: flow` with a run cap of 50000000 microusd.
37
+
38
+ | Id | lead | worker | reviewer | qa |
39
+ | --- | --- | --- | --- | --- |
40
+ | `premium` | `openai-codex/gpt-6.1-sol` | `openai-codex/gpt-6-luna` | `openai-codex/gpt-6.1-sol` | `anthropic/claude-sonnet-5-5` |
41
+ | `anthropic` | `anthropic/claude-opus-5-5` | `anthropic/claude-sonnet-5` | `anthropic/claude-sonnet-5` | `anthropic/claude-sonnet-5` |
42
+ | `openai` | `openai-codex/gpt-6.1-sol` | `openai-codex/gpt-6-luna` | `openai-codex/gpt-6.1-sol` | `openai-codex/gpt-6.1-sol` |
43
+ | `oss-first` | `humain-node/glm-5.2` | `humain-node/glm-5.2` | `humain-node/glm-5.2` | `humain-node/glm-5.2` |
44
+
45
+ Built-ins cannot be saved over or deleted (`profile_builtin_readonly`). Clone one to customize it. The ids are reserved: a file with a built-in id in the user directory is reported as `profile_id_reserved` and not loaded.
46
+
47
+ ## Storage layout
48
+
49
+ All paths are under the agent directory:
50
+
51
+ ```
52
+ <agentDir>/flow/
53
+ active-profile.json active pointer
54
+ profiles/
55
+ <id>.json one file per user profile
56
+ .store.lock mutation lock
57
+ .backups/
58
+ <id>.v<version>.<ms>-<8hex>.json previous versions
59
+ <id>.corrupt.<ms>-<8hex>.json raw bytes of a removed unparseable profile
60
+ .<id>.watermark.json highest RESERVED version for the id (a failed publish can leave a gap)
61
+ ```
62
+
63
+ `active-profile.json` contains `{ "schema": "humain-flow-active-profile", "schemaVersion": 1, "id": "<id>" }`.
64
+
65
+ Safety checks:
66
+
67
+ - `flow`, `profiles`, and `.backups` must be real directories (not symlinks), owned by the current user, and not group- or world-writable. Otherwise the store fails with `store_unsafe`. Missing directories are created level by level with mode `0700`; each directory and every ancestor up to the filesystem root are `fsync`ed at the start of every mutation (ancestors that cannot be opened with `EACCES` are skipped), so a retry after a failed `fsync` cannot skip the barrier. Directory `fsync` errors `EINVAL`, `EPERM`, and `EISDIR` (unsupported filesystems) are ignored; all other errors abort the operation.
68
+ - Files are opened without following symlinks, must be regular files, and are limited to 256 KiB (`profile_too_large`).
69
+ - A profile file must be named `<id>.json` and its `id` must match the file name.
70
+
71
+ ## Saving
72
+
73
+ Every save (editor edit, clone, import) goes through the store lock and:
74
+
75
+ 1. Checks that the on-disk version and digest equal those the edit started from (`baseVersion`, and `baseDigest`, which defaults to the draft's `digest`). A mismatch gives `profile_conflict` (changed on disk) or `profile_exists` (creating a profile that exists).
76
+ 2. Sets `version` to the highest of the on-disk version, any backed-up version, and the per-id version watermark (`.backups/.<id>.watermark.json`), plus 1. The watermark records the highest reserved version: a failed publish can leave a gap, and versions are never reused for ids that have a watermark. Ids without a watermark (profiles never saved through the store) can reuse a version number, but the digest check still rejects stale saves. The watermark does not depend on any profile file parsing, so a deleted (even corrupt) and recreated profile never reuses a version, and a stale draft cannot overwrite it. An unreadable or invalid watermark fails the save with `store_unsafe`; it is never reset.
77
+ 3. Recomputes `digest` and validates the result.
78
+ 4. Writes the previous file bytes to `.backups/<id>.v<version>.<ms>-<8hex>.json`, then `fsync`s the `.backups` directory. If the backup or its `fsync` fails, the save aborts and the original is untouched.
79
+ 5. Writes the watermark atomically, then the new file atomically: temp file `<file>.<pid>.<uuid>.tmp`, `fsync`, rename, then `fsync` of the containing directory. Files are created with mode `0600`.
80
+ 6. Prunes backups. The newest 10 versions per id and the newest 10 corrupt backups are kept. Pruning never fails a save.
81
+
82
+ `remove` writes and `fsync`s a backup of the file first (aborting if that fails), deletes the profile, `fsync`s the `profiles` directory, and clears `active-profile.json` if it pointed at that id. An unparseable file is backed up as `<id>.corrupt.<ms>-<8hex>.json`.
83
+
84
+ ### Lock
85
+
86
+ One lock file, `profiles/.store.lock`, serializes every mutation (save, clone, remove, `use`, import). It is created exclusively with mode `0600` and holds `{ pid, token }`. It is released only if it still holds the owner's token.
87
+
88
+ If a second writer finds the lock, it fails immediately with `profile_locked`. There is no waiting and no age-based reclamation.
89
+
90
+ To recover from a stale lock (for example after a crash): confirm no other HUMAIN Code process is editing profiles, then delete `<agentDir>/flow/profiles/.store.lock`.
91
+
92
+ ### Corrupt files
93
+
94
+ Listing never throws for a bad user profile. Invalid JSON, failed validation, digest mismatch, id/file-name mismatch, oversize files, and reserved ids are reported as problems with the file path and an error code. The remaining profiles still load. Problem messages never include file content.
95
+
96
+ ## Resolution order
97
+
98
+ `resolveProfile(id?)` picks a profile in this order:
99
+
100
+ 1. The explicit id, if given. Failure throws the underlying error (for example `profile_not_found`).
101
+ 2. The active profile from `active-profile.json`.
102
+ 3. `premium`, when no active pointer exists.
103
+
104
+ A malformed active pointer, or one naming a profile that cannot be loaded, throws `active_profile_invalid`. It never falls back silently to `premium`.
105
+
106
+ The result carries the profile and a frozen reference `{ id, version, digest }`.
107
+
108
+ ## `/flow-profile` command
109
+
110
+ ```
111
+ Usage: /flow-profile [subcommand]
112
+ list list profiles
113
+ show <id> show a profile
114
+ use <id> set the active profile
115
+ export <id> print a profile as JSON
116
+ import <file> [--replace] import a profile file
117
+ validate <file> validate a profile file
118
+ No subcommand opens the interactive editor.
119
+ ```
120
+
121
+ - `list` marks the active profile with `*`, shows version and source (`builtin` or `user`), and lists problems.
122
+ - `use` fails if the profile does not load.
123
+ - `import` resolves `<file>` against the working directory. It strips `approval`, rejects built-in ids (`profile_id_reserved`) and files marked `builtIn`, and creates a new profile. If the id exists it fails with `profile_exists` unless `--replace` is given. The imported profile is re-saved, so its version and digest are recomputed.
124
+ - `validate` checks a file without importing it.
125
+ - An unknown subcommand prints the usage text. With no subcommand and no UI, the command runs `list`.
126
+
127
+ Output is stripped of ANSI escapes and control characters before display, because imported profile text is untrusted.
128
+
129
+ ### Interactive editor
130
+
131
+ With no subcommand and a UI available, the command opens an editor. The top level lists all profiles (active one marked) and a `Close` entry. Selecting a profile opens its menu:
132
+
133
+ - Built-in profiles: `View`, `Set active`, `Clone`, `Back`.
134
+ - User profiles: also `Edit role` (only for `kind: flow`), `Edit limits`, `Edit spend cap`, and `Delete` (asks for confirmation).
135
+
136
+ Edits prompt for text values: role primary as `provider/model`, fallbacks as a comma-separated list (empty keeps the current value, `none` clears), effort, a limit field and integer value, run cap in microusd, and warn percent (1 to 99). Invalid input is shown as an error and nothing is saved. Each save bumps the version as described above.
137
+
138
+ The editor only uses the standard `select`, `confirm`, and `input` dialogs. It adds no key bindings. Navigation uses the configurable `tui.select.*` bindings (see [keybindings.md](keybindings.md)).
139
+
140
+ ## Selecting a profile for a run
141
+
142
+ A run selects a profile with `--profile <id>`. If the flag is omitted, the active profile, then `premium`, is used (see Resolution order). The `--profile <id>` flag and the writing of `runs/<id>/admission.json` are NOT part of this change. They are provided by the Flow loader integration (stream A2, pending). B1 provides only `resolveProfile` and `buildCliAdmission`.
143
+
144
+ `buildCliAdmission` freezes the resolved profile into the admission document for the run:
145
+
146
+ - The full profile content is embedded, including `{ id, version, digest }`, so later edits to the stored profile do not change a running or recorded run.
147
+ - `spendCapMicrousd` defaults to the profile's `spend.runCapMicrousd`.
148
+ - A spend cap override must be a safe integer from 0 up to `runCapMicrousd`. Otherwise it fails with `spend_cap_exceeded`.
149
+ - `mode` is `direct` for `kind: direct` profiles and `auto` for `kind: flow`.
150
+ - The document gets its own `admissionDigest` and is validated before it is returned.
151
+
152
+ ## Error codes
153
+
154
+ | Code | Meaning |
155
+ | --- | --- |
156
+ | `profile_not_found` | No profile with that id or path. |
157
+ | `profile_invalid` | Bad id, invalid JSON, failed validation or digest check, id/file-name mismatch, unreadable or non-regular file, or a user profile marked built-in. |
158
+ | `profile_builtin_readonly` | Attempt to save over or delete a built-in profile. |
159
+ | `profile_id_reserved` | Id belongs to a built-in (import, or a stray file in the user directory). |
160
+ | `profile_locked` | Another writer holds `.store.lock`. |
161
+ | `profile_conflict` | The profile changed on disk since the edit started. |
162
+ | `profile_exists` | Creating or importing a profile whose id already exists (without `--replace`). |
163
+ | `active_profile_invalid` | The active pointer is malformed or names a profile that cannot load. |
164
+ | `profile_too_large` | File exceeds 256 KiB. |
165
+ | `store_readonly` | No agent flow directory is configured, so the store cannot be written. |
166
+ | `store_unsafe` | A store directory is a symlink, foreign-owned, or group/world-writable, or the version watermark is unreadable or invalid. |
167
+ | `spend_cap_exceeded` | Spend cap override is not an integer in 0 to `runCapMicrousd`. |
168
+
169
+ ## Telemetry
170
+
171
+ Flow telemetry events contain no free text: only ids, digests, enum values, and timestamps (see the contracts package `docs/flow-contracts.md`). Profile `label` and `description` are display text and are never emitted in telemetry. Profile ids are emitted, so do not put secrets or user text in an id.
172
+
173
+ See [Flow profiles: admin reference](../../flow/docs/profiles.md) for built-in model tables, storage, and validation details.
package/docs/flow.md ADDED
@@ -0,0 +1,112 @@
1
+ # Flow
2
+
3
+ Flow is the hierarchical agent harness built into HUMAIN Code. `/flow <goal>` plans a task, dispatches child agents (scouts, leads, workers, reviewers, QA), verifies the result, and reports it. This guide describes what is implemented in this checkout. Items that are not implemented are tagged `(planned)` with the plan section that covers them (the Flow harness implementation plan, streams A1, A2, A3, C1).
4
+
5
+ ## Flow versus direct prompts
6
+
7
+ A plain prompt goes to the normal session and never touches Flow. Flow runs only when you invoke one of its commands. Flow code is not loaded at startup: HUMAIN Code registers lightweight stub commands plus the `--profile` flag, and the first stub invocation performs one memoized dynamic import of the bundled Flow package. A failed load is reported as `Failed to load Flow: <message>` and is retried on the next invocation.
8
+
9
+ Stub commands: `/flow`, `/flow-continue`, `/flow-status`, `/flow-cancel`, `/flow-pause`, `/flow-resume`, `/flow-title`, `/flow-models`, `/flow-profile`, `/omsg`.
10
+
11
+ ## `/flow <goal>`
12
+
13
+ ```
14
+ /flow <goal> [--task-class T] [--complexity N] [--risk low|medium|high|critical]
15
+ [--profile NAME] [--lead-size small|standard|large]
16
+ [--workflow direct|checked|led|full]
17
+ [--cheap ALIAS] [--mid ALIAS] [--premium ALIAS] [--frontier ALIAS]
18
+ [--model <capability>=ALIAS] [--effort LEVEL]
19
+ [--quality-floor F] [--cost-aggressiveness C] [--max-retries R]
20
+ [--context FILE ...] [--with-last-reply] [--force]
21
+ ```
22
+
23
+ Flags are honored only before or after the goal text. A `--flag` between goal words is part of the goal. Unrecognized flags are reported, not silently dropped. Values are not all validated by the parser: `--complexity` is rounded and clamped to 1-10, and a non-numeric value falls back to 5. `--risk` and `--task-class` are stored as given, and the parser does not check them against a list of allowed values. The parser also accepts other flags (`--fan-out`, `--candidate`, `--route-only`, `--live-qa`, `--no-live-qa`, `--live-qa-adapter`, `--live-qa-scope`, `--live-qa-acceptance`, `--check`); this guide covers only the flags above.
24
+
25
+ Auto mode:
26
+
27
+ - With no triage flags, an LLM triage call fills in task class, complexity, and risk from the goal. The triage model is the first available binding of `implementation_fast`, `worker`, `scout`, then the first adapter binding; it is not chosen by price. If triage fails or no model is dispatchable, the defaults remain (`src/extension.ts:2176-2192,2341`).
28
+ - There is no approval step. Runs auto-approve by default. `--yes` and `-y` are accepted as no-ops.
29
+ - The command parses flags and starts the run in the background; the command handler returns while the run continues. Triage and workflow signal collection run inside the run, so the first dispatch is not instant.
30
+
31
+ ## Sizes and workflows
32
+
33
+ Flow has four workflow levels: `direct`, `checked`, `led`, `full`.
34
+
35
+ | Size | Workflow | Meaning |
36
+ |---|---|---|
37
+ | small | `checked` | one implementer plus deterministic repo checks |
38
+ | medium | `led` | lead plus workers, review, QA |
39
+ | large | `full` | architect, recon, several leads, review, QA |
40
+
41
+ The mapping is implemented as a pure function (`sizeToWorkflow`), and a rules-then-triage size decision exists (`decideSize`: rule classifier first, triage only when rules say medium or large). **Neither is called by the `/flow` run path yet.** Wiring size-based auto mode into `/flow` is `(planned)` (plan section 3 A3, deliverable 3; A2).
42
+
43
+ What `/flow` does today to pick a level:
44
+
45
+ - A router reads repository evidence: risk path globs, interface changes across packages, candidate file count, nearby tests, and discovered checks. High risk or a protected path forces `full`. Wide scope or unresolved scope gives `led`. A single localized low-risk file with tests gives `direct`. Otherwise `checked`.
46
+ - The workflow mode controls how much of this applies: `off` (no routing), `observe` (default in `method.json`; plans and records, runs lead/full hierarchy), `enforce` (also runs the flat `direct`/`checked` path). Show or persist it with `/flow-models workflow [off|observe|enforce|default]`. The env var `HUMAIN_ORCHESTRATOR_WORKFLOW_MODE` overrides the saved setting.
47
+ - `--workflow <level>` overrides the routed level, but never below the hard floor; a lower request is rejected and recorded.
48
+ - `--lead-size small|standard|large` sets the lead size directly. Otherwise lead size comes from triage complexity and risk.
49
+
50
+ ### Size override
51
+
52
+ A user-facing `--size small|medium|large` flag does not exist. The engine-level equivalent today is `--workflow`. A `--size` override is `(planned)` (plan section 3 A3 deliverable 3; section 3 D2 deliverable 1).
53
+
54
+ ### Escalation
55
+
56
+ - A fresh flat run (`direct`/`checked`) can escalate once to `led` when progress-aware repair requests escalation and retry budget remains. Prior work and failure evidence carry forward. An escalated re-run is never escalated flat again. This only applies in `enforce` mode, because flat runs happen only there.
57
+ - Escalation is not guaranteed. Provider failures, unsafe or unverified scope, blocked work, a read-only task, and an exhausted or explicit retry budget can stop the run without escalation (`src/pipeline/run-orchestration.ts:3090-3137,3351-3365`; `src/pipeline/repair-policy.ts:130-144`).
58
+ - On verification failure, retry leads can move up one lead capability tier.
59
+ - Escalation from medium to large as a size transition, with an `escalated` telemetry event, is `(planned)` (plan section 3 A2, deliverable 12; section 4.3).
60
+
61
+ ## `--profile`
62
+
63
+ `hc --profile <id>` registers a string flag. When `/flow` runs, it validates the id against `^[a-z0-9][a-z0-9_.:-]{0,127}$` and uses it unless `/flow` itself carried `--profile`. An invalid id is rejected with an error.
64
+
65
+ Today the id selects a profile in `orchestrator-profiles.json` (model bindings per tier and capability). Precedence for models is: flags, then profile, then the cost-tier resolver. An id not defined in that file produces a warning. Manage these with `/flow-models`.
66
+
67
+ The versioned Flow profile store and the frozen run admission (`resolveProfile`, `buildCliAdmission`) exist in the Flow package but are not called by the `/flow` run path. Selecting them with `--profile`, and writing `admission.json` for each run, is `(planned)` (plan section 3 A2 deliverables 6 and 9; section 3 B1 deliverable 5). See [flow-profiles.md](flow-profiles.md). `hc --flow-admission <file>` is a string startup flag; it is authoritative for every `/flow` in the session: `/flow --profile` and `/flow --flow-admission <other file>` are refused before dispatch, and the same path is allowed.
68
+
69
+ ## Run control and inspection
70
+
71
+ | Command | Behavior |
72
+ |---|---|
73
+ | `/flow-status` | Opens the live orchestration board (TUI only; Esc closes it without cancelling the run). Outside the TUI it points to the `orchestrator_status` tool. Reports "No orchestrator run is active." when idle. |
74
+ | `/flow-cancel` | Cancels the active run (reason `user`). Reports "no active run" when idle. |
75
+ | `/flow-title <title>` | Renames the active flow and shows the title on the widget border. Errors with "no active run" when idle. |
76
+ | `/flow-continue [run-id]` | Previews recovery of an interrupted run in its original checkout and asks for explicit confirmation. TUI only. There is no `--yes` or `--force`. With several candidates it lists them and requires an explicit run id. It blocks when ownership, bindings, or process-lineage evidence is unsafe, and asks you to confirm each unresolved external effect. |
77
+ | `/flow-models <sub>` | Subcommands: `show`, `list`, `validate [--live]`, `check`, `set`, `effort`, `use`, `new`, `pick`, `workflow`. Aliases such as `fable-5-1`, `opus-5-5`, `sonnet-5`, `gpt-6-sol`, `gpt-6-luna`, `astra` resolve against your configured models. |
78
+ | `/flow-profile` | Registered as a stub only. The Flow package exports a command implementation, but it is not registered, so the stub answers `/flow-profile is not available yet`. Registering it is `(planned)` (plan section 3 B1, deliverables 3 and 4). |
79
+
80
+ ### Pause and resume `(planned)`
81
+
82
+ `/flow-pause` and `/flow-resume` are loader stubs with no Flow implementation. Invoking them after Flow loads prints `/flow-pause is not available yet` (or `/flow-resume ...`). Planned semantics (plan section 3 A2 deliverables 7 and 8; section 4.4): stop new dispatch, let running children finish their current turn, then hold until resume. Run-control contracts exist in `packages/humain-code-contracts/src/flow-control.ts`. The runtime control handlers (`flow_pause`, `flow_resume`, `flow_status`, `flow_cancel`, `flow_message`) and the `packages/flow/src/control/` module do not exist in this checkout and are `(planned)`.
83
+
84
+ ### Mid-run messages: `/omsg <text>`
85
+
86
+ `/omsg` queues a message for the running run. The message is appended to the prompt of the next dispatched task. It is not injected into a running child, because children run without a stdin channel. A literal `\n` becomes a newline. Messages are truncated to a length cap, and the oldest message is dropped when the queue is full. With no active run it warns and does nothing.
87
+
88
+ Live delivery to the running lead, with queued delivery only in direct mode, is `(planned)` (plan section 3 A2 deliverable 7; section 4.4). Today `/omsg` is always queued.
89
+
90
+ ## Kill switch
91
+
92
+ Flow can be disabled without affecting direct prompts. Either of these makes every Flow command answer `Flow disabled (<reason>). /<command> is unavailable.` before anything loads:
93
+
94
+ - Environment variable `HUMAIN_TERMINAL_FLOW_DISABLED` set to `1` or `true` (case-insensitive, trimmed).
95
+ - Setting `flow.enabled` set to `false` in `settings.json`.
96
+
97
+ Plain prompts do not go through Flow, so they keep working.
98
+
99
+ ## Failure handling
100
+
101
+ - Terminal outcomes are `completed`, `failed`, or `cancelled`. A failed run is reported as a terminal notification with a title and reason text (for example "Orchestration needs attention" or "Orchestration crashed"). Each lead report carries a status of `completed`, `partial`, `blocked`, or `unknown` (parsed from its `STATUS:` line). The aggregate run outcome is separate: `blocked`, `dispatched`, or `failed`. It is `failed` when there are no leads or no lead exited cleanly, and `blocked` only when every lead exits cleanly and reports `blocked` (`src/run-outcome.ts:18-27,48-66`).
102
+ - Flow does not re-run a failed `/flow` as a direct prompt. I found no such code path, so a failed run is reported, not hidden.
103
+ - After a failed fresh CLI run, Flow shows the failure class (for example `Flow run failed (crash)`) and offers "Retry as Flow" or "Retry direct" through a select. Dismissing the select does nothing. There is no offer for cancelled, `budget_stop`, recovered (`/flow-continue`) or `--flow-admission` runs. "Retry as Flow" respects the kill switch and starts a new run; "Retry direct" sends the goal as a normal prompt.
104
+ - Contracts for the typed settlement fields (`run_settled`, `failureClass`, `retryOffer`) exist in `packages/humain-code-contracts/src/flow-events.ts`. The spend cap enforced from an admission is `(planned)` (plan sections 3 C1, 4.3).
105
+ - Spend limits today: the per-dispatch cap in `method.json` (`dispatch_spend_cap`, default mode `warn`), and the run cancellation when reported plus estimated spend exceeds `SENTINEL_CHILD_MAX_COST_USD` from a HUMAIN Sentinel parent (`packages/flow/src/extension.ts:1155-1163`).
106
+
107
+ ## Related
108
+
109
+ - [flow-profiles.md](flow-profiles.md)
110
+ - [Flow profiles reference](../../flow/docs/profiles.md)
111
+ - [Known limits](../../flow/docs/known-limits.md)
112
+ - [Migration](../../flow/docs/migration.md)
package/docs/index.md CHANGED
@@ -41,6 +41,8 @@ HUMAIN Code CLI's tools and extensions run with the permissions of the HUMAIN Co
41
41
  ## HUMAIN Code CLI integrations
42
42
 
43
43
  - [HUMAIN Code CLI](humain-code.md) - branded command names, bundled web access/MCP integration, HUMAIN Node, and Forge/DeployNow setup.
44
+ - [Run Flow](flow.md) - hierarchical Flow runs with `/flow`, run controls, and limits.
45
+ - [Configure Flow Profiles](flow-profiles.md) - Flow profile models, limits, and spend caps.
44
46
  - [Agent activity traces](trace.md) - proposal: record, upload and review what an agent did during a run.
45
47
  - [HUMAIN Code / Forge Architecture](humain-code-forge-architecture.md) - architecture principles and layer ownership.
46
48
  - [HUMAIN Code / Forge Flow Walkthrough](humain-code-forge-flow-walkthrough.md) - current startup and provider-binding data flow.
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@humain/humain-code",
3
- "version": "0.3.8",
3
+ "version": "0.4.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@humain/humain-code",
9
- "version": "0.3.8",
9
+ "version": "0.4.1",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@humain/humain-code-contracts": "0.3.3",
12
+ "@humain/humain-code-contracts": "0.4.1",
13
13
  "@aws-sdk/client-bedrock-runtime": "3.1146.0",
14
14
  "@earendil-works/pi-agent-core": "1.1.0",
15
15
  "@earendil-works/pi-ai": "1.1.0",
@@ -1024,9 +1024,9 @@
1024
1024
  "hasInstallScript": true
1025
1025
  },
1026
1026
  "node_modules/@humain/humain-code-contracts": {
1027
- "version": "0.3.3",
1028
- "resolved": "https://registry.npmjs.org/@humain/humain-code-contracts/-/humain-code-contracts-0.3.3.tgz",
1029
- "integrity": "sha512-20VmH2kTBufCACOXIKCsJ1a06aA7s03eCYpZDr5L6nq5sq7EuWZ8GXq01AHDsdKl1Oc+MNKaOQxKO0HMI7K+1Q==",
1027
+ "version": "0.4.1",
1028
+ "resolved": "https://registry.npmjs.org/@humain/humain-code-contracts/-/humain-code-contracts-0.4.1.tgz",
1029
+ "integrity": "sha512-a1t8577LgoOeHnU/uND3VMfzVG7f+ClYLqNKYIT44NpDKFirMKEQ7UolKyDPmF6bfHHvrl6dZXDOHcEsZbNYJA==",
1030
1030
  "license": "MIT",
1031
1031
  "dependencies": {
1032
1032
  "typebox": "1.3.35"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humain/humain-code",
3
- "version": "0.3.8",
3
+ "version": "0.4.1",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "humainTerminalConfig": {
@@ -76,17 +76,17 @@
76
76
  ],
77
77
  "scripts": {
78
78
  "clean": "shx rm -rf dist",
79
- "build": "npm run build:unbundled && node ../../scripts/build-coding-agent-bundle.mjs",
79
+ "build": "npm run build:unbundled && npm --prefix ../flow run build && node ../../scripts/build-coding-agent-bundle.mjs",
80
80
  "build:unbundled": "tsc -p tsconfig.build.json && shx chmod +x dist/cli.js dist/rpc-entry.js && npm run copy-assets",
81
- "build:binary": "npm --prefix ../tui run build && npm --prefix ../telemetry run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm --prefix ../protocol run build && npm --prefix ../client run build && npm run build && bun build --compile --no-compile-autoload-bunfig --no-compile-autoload-dotenv ./src/bun/cli.ts ./src/utils/image-resize-worker.ts ./src/extensions/codemode/worker.ts --outfile dist/pi && npm run copy-binary-assets",
81
+ "build:binary": "npm --prefix ../tui run build && npm --prefix ../telemetry run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm --prefix ../protocol run build && npm --prefix ../client run build && npm --prefix ../humain-code-contracts run build && npm run build && bun build --compile --no-compile-autoload-bunfig --no-compile-autoload-dotenv ./src/bun/cli.ts ./src/utils/image-resize-worker.ts ./src/extensions/codemode/worker.ts --outfile dist/pi && npm run copy-binary-assets",
82
82
  "copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/modes/interactive/assets && shx cp src/modes/interactive/assets/*.png dist/modes/interactive/assets/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/ && shx mkdir -p dist/humain/bedrock-provider/vendor && shx cp -r src/humain/bedrock-provider/vendor/* dist/humain/bedrock-provider/vendor/",
83
- "copy-binary-assets": "shx cp package.json dist/ && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/assets && shx cp src/modes/interactive/assets/*.png dist/assets/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html dist/export-html/ && shx cp src/core/export-html/vendor/*.js dist/export-html/vendor/ && shx cp -r docs dist/ && shx cp -r examples dist/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/ && shx mkdir -p dist/humain-modules/ponytail dist/humain-modules/caveman && shx cp -r src/humain/ponytail/vendor/skills src/humain/ponytail/vendor/LICENSE dist/humain-modules/ponytail/ && shx cp -r src/humain/caveman/vendor/skills src/humain/caveman/vendor/LICENSE src/humain/caveman/vendor/LICENSE-MIT src/humain/caveman/vendor/NOTICE dist/humain-modules/caveman/ && shx mkdir -p dist/humain-modules/adhd && shx cp -r src/humain/adhd/vendor/skills src/humain/adhd/vendor/LICENSE dist/humain-modules/adhd/ && shx mkdir -p dist/humain-modules/coordination && shx cp src/coordination/vendor/LICENSE dist/humain-modules/coordination/",
83
+ "copy-binary-assets": "shx cp package.json dist/ && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/assets && shx cp src/modes/interactive/assets/*.png dist/assets/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html dist/export-html/ && shx cp src/core/export-html/vendor/*.js dist/export-html/vendor/ && shx cp -r docs dist/ && shx cp -r examples dist/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/ && shx mkdir -p dist/humain-modules/ponytail dist/humain-modules/caveman && shx cp -r src/humain/ponytail/vendor/skills src/humain/ponytail/vendor/LICENSE dist/humain-modules/ponytail/ && shx cp -r src/humain/caveman/vendor/skills src/humain/caveman/vendor/LICENSE src/humain/caveman/vendor/LICENSE-MIT src/humain/caveman/vendor/NOTICE dist/humain-modules/caveman/ && shx mkdir -p dist/humain-modules/adhd && shx cp -r src/humain/adhd/vendor/skills src/humain/adhd/vendor/LICENSE dist/humain-modules/adhd/ && shx mkdir -p dist/humain-modules/coordination && shx cp src/coordination/vendor/LICENSE dist/humain-modules/coordination/ && shx mkdir -p dist/flow && shx cp -r ../flow/agents ../flow/assets ../flow/package.json dist/flow/",
84
84
  "test": "vitest --run",
85
85
  "shrinkwrap": "node ../../scripts/generate-coding-agent-shrinkwrap.mjs",
86
86
  "prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap"
87
87
  },
88
88
  "dependencies": {
89
- "@humain/humain-code-contracts": "0.3.3",
89
+ "@humain/humain-code-contracts": "0.4.1",
90
90
  "@aws-sdk/client-bedrock-runtime": "3.1146.0",
91
91
  "@earendil-works/pi-agent-core": "1.1.0",
92
92
  "@earendil-works/pi-ai": "1.1.0",
@@ -135,6 +135,7 @@
135
135
  "@mariozechner/clipboard": "0.3.9"
136
136
  },
137
137
  "devDependencies": {
138
+ "@humain/flow": "0.4.0-flow.0",
138
139
  "@types/cross-spawn": "6.0.6",
139
140
  "@types/diff": "8.0.0",
140
141
  "@types/hosted-git-info": "3.0.5",