hirmos 1.3.2 → 1.3.4

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
@@ -1,85 +1,39 @@
1
1
  # HIRMOS CLI
2
2
 
3
- Product-facing HIRMOS CLI.
3
+ The HIRMOS CLI is the terminal installer for the HIRMOS framework payload and AI-tool integration files.
4
4
 
5
- Implemented command:
5
+ It is intentionally small. HIRMOS framework workflow commands such as `hirmos start`, `hirmos status`, `hirmos continue`, and `hirmos close` are commands for the LLM/agent inside supported integration tools after initialization. They are not terminal CLI commands.
6
+
7
+ ## Implemented CLI commands
6
8
 
7
9
  ```bash
8
10
  hirmos init [project-path] [--integration <ids>] [--source <path>] [--version <version>] [--offline]
9
11
  ```
10
12
 
11
- The CLI makes an installed HIRMOS project discoverable to selected agent-native tools by generating thin bootstrap integration files from `_hirmos/integrations/agent-tools/`.
12
-
13
- It does not invoke agents, run HIRMOS workflows, install extensions, or generate slash-command packs.
14
-
15
- ## Usage
16
-
17
- From a project root:
18
13
 
19
- ```bash
20
- hirmos init
21
- ```
14
+ ## Integration template ownership
22
15
 
23
- If `_hirmos/` is not present, the CLI downloads the latest HIRMOS framework release package and installs `_hirmos/` before generating integrations.
24
-
25
- This defaults to:
16
+ `tools/cli` installs integration templates; it does not own them. The canonical integration registry and templates live in the framework payload at:
26
17
 
27
18
  ```text
28
- project-path = .
29
- integration = agents
30
- source = existing _hirmos/ in the project, otherwise latest GitHub release
31
- version = latest
32
- ```
33
-
34
- Generate specific integrations:
35
-
36
- ```bash
37
- hirmos init --integration claude,cursor,copilot
38
- ```
39
-
40
- Initialize another project path:
41
-
42
- ```bash
43
- hirmos init /path/to/project --integration agents,claude
44
- ```
45
-
46
- Install a specific HIRMOS release:
47
-
48
- ```bash
49
- hirmos init --version 1.3.1
19
+ _hirmos/integrations/agent-tools/
50
20
  ```
51
21
 
52
- Install `_hirmos/` from a local source folder or release zip instead of downloading:
22
+ Maintainers should update integration definitions in `_private/_hirmos/integrations/agent-tools/`, propagate them to `_public/_hirmos/integrations/agent-tools/`, regenerate `ops/dist/hirmos-framework.zip`, and then verify `hirmos init` against the regenerated framework payload.
53
23
 
54
- ```bash
55
- hirmos init /path/to/project --source /path/to/hirmos-framework.zip --integration agents
56
- ```
57
-
58
- Disable remote download and require an existing `_hirmos/` or local `--source`:
59
-
60
- ```bash
61
- hirmos init --offline
62
- ```
24
+ ## What `hirmos init` does
63
25
 
64
- ## CLI update notice
26
+ `hirmos init` prepares a project to use HIRMOS by:
65
27
 
66
- When `hirmos init` runs online, it checks whether a newer published HIRMOS CLI version is available on npm. If a newer version exists, the CLI prints a non-blocking message such as:
67
-
68
- ```text
69
- A newer HIRMOS CLI is available: 1.3.2.
70
- Update with: npm install -g hirmos@latest
71
- ```
72
-
73
- The notice does not stop initialization. Network failures, registry errors, or timeouts are ignored.
74
-
75
- Use `--offline` to disable both remote framework download and the update check. To disable only the update notice while keeping remote framework download available, run:
76
-
77
- ```bash
78
- HIRMOS_CLI_UPDATE_CHECK=0 hirmos init
79
- ```
28
+ 1. Installing `_hirmos/` if the project does not already have it.
29
+ 2. Validating that the installed framework payload is complete enough for initialization.
30
+ 3. Generating or updating selected AI-tool integration files using managed HIRMOS blocks.
31
+ 4. Recording selected integrations in `_hirmos/hirmos.config.json`.
80
32
 
81
33
  ## Supported integrations
82
34
 
35
+ `--integration` accepts comma-separated integration ids. Current ids:
36
+
83
37
  ```text
84
38
  agents
85
39
  claude
@@ -92,48 +46,59 @@ windsurf
92
46
  kiro
93
47
  ```
94
48
 
95
- Some integrations share the same target file. For example, `agents`, `codex`, and `opencode` all use `AGENTS.md` as the safe generic bootstrap target.
49
+ Default:
96
50
 
97
- ## Managed-block behavior
51
+ ```bash
52
+ hirmos init
53
+ ```
98
54
 
99
- For existing files, the CLI updates only the HIRMOS managed block:
55
+ This installs the generic `agents` integration.
100
56
 
101
- ```md
102
- <!-- HIRMOS:START -->
103
- ...
104
- <!-- HIRMOS:END -->
57
+ Examples:
58
+
59
+ ```bash
60
+ hirmos init --integration agents,claude,cursor
61
+ hirmos init ./my-project --integration agents,copilot,codex,opencode
62
+ hirmos init ./my-project --source ./hirmos-framework.zip --offline
105
63
  ```
106
64
 
107
- If the file exists and has no HIRMOS block, the CLI appends one. User-owned content outside the block is preserved.
65
+ ## Source selection
108
66
 
109
- ## Project config behavior
67
+ By default, if the target project already has `_hirmos/`, the CLI uses that framework payload. If the target project does not have `_hirmos/`, the CLI downloads the selected GitHub release unless `--source` or `--offline` changes that behavior.
110
68
 
111
- The CLI merges selected integration IDs into:
69
+ `--source` may point to:
112
70
 
113
- ```text
114
- _hirmos/project.json
115
- ```
71
+ - an `_hirmos/` directory
72
+ - a folder containing `_hirmos/`
73
+ - a `hirmos-framework.zip` release package
74
+
75
+ `--offline` disables remote release download and requires either an existing `_hirmos/` or `--source`.
76
+
77
+ ## Update notice
116
78
 
117
- under:
79
+ When `hirmos init` runs online, it checks whether a newer published HIRMOS CLI version is available on npm. If a newer version exists, the CLI prints a non-blocking message. The check can be disabled:
118
80
 
119
- ```json
120
- {
121
- "integrations": {
122
- "installed": []
123
- }
124
- }
81
+ ```bash
82
+ HIRMOS_CLI_UPDATE_CHECK=0 hirmos init
125
83
  ```
126
84
 
127
- Re-running `hirmos init --integration ...` is additive and does not remove previously recorded integrations.
85
+ ## After initialization
86
+
87
+ Open the project in the selected AI coding tool. The generated integration file is the normal bootstrap path for that tool.
128
88
 
129
- ## Workflow commands are not CLI commands
89
+ If the integration file is not available or the tool did not load it, use this fallback bootstrap prompt inside the agent conversation:
90
+
91
+ ```text
92
+ Read and follow _hirmos/AGENTS.md
93
+ ```
130
94
 
131
- These are HIRMOS workflow commands to use inside the AI tool after HIRMOS Core has loaded:
95
+ Then use HIRMOS framework workflow commands inside the agent conversation, for example:
132
96
 
133
97
  ```text
134
- hirmos requirements
135
- hirmos system-design
136
- hirmos implementation
98
+ hirmos start
99
+ hirmos status
100
+ hirmos continue
101
+ hirmos close
137
102
  ```
138
103
 
139
- The CLI implements `hirmos init`.
104
+ Those workflow commands are governed by the framework instructions and active session artifacts, not by this terminal CLI.
@@ -58,7 +58,16 @@ function formatInitSummary(first, selected, added, alreadyInstalled, targets, in
58
58
  for (const target of targets)
59
59
  lines.push(`- ${target}`);
60
60
  lines.push("", "Next step:");
61
- lines.push("Open your AI coding tool and ask it to read and follow _hirmos/HIRMOS_CORE.md.");
61
+ lines.push("Open your AI coding tool in this project and ask the agent to run a HIRMOS framework workflow command, for example:");
62
+ lines.push("");
63
+ lines.push("hirmos start");
64
+ lines.push("hirmos status");
65
+ lines.push("hirmos continue");
66
+ lines.push("");
67
+ lines.push("Fallback agent instruction:");
68
+ lines.push("If your tool does not automatically pick up the selected agent/tool integration files, copy and paste this prompt into your agent:");
69
+ lines.push("");
70
+ lines.push("Read and follow the instructions on _hirmos/AGENTS.md.");
62
71
  lines.push("", "To add more integrations later:");
63
72
  lines.push("hirmos init --integration claude,cursor,copilot");
64
73
  return `${lines.join("\n")}\n`;
package/dist/lib/args.js CHANGED
@@ -14,8 +14,8 @@ function parseArgs(argv) {
14
14
  return { command: "help" };
15
15
  }
16
16
  const command = argv[0];
17
- if (command !== "init") {
18
- (0, errors_1.fail)(`Unsupported command: ${command}. This CLI currently supports: hirmos init`);
17
+ if (!command || command !== "init") {
18
+ (0, errors_1.fail)(`Unsupported command: ${command}. This CLI supports: hirmos init`);
19
19
  }
20
20
  let projectPath = ".";
21
21
  let projectPathSet = false;
@@ -101,5 +101,24 @@ function parseIntegrationList(value) {
101
101
  return ids;
102
102
  }
103
103
  function helpText() {
104
- return `HIRMOS CLI\n\nUsage:\n hirmos init [project-path] [--integration <ids>] [--source <path>] [--version <version>] [--offline]\n\nDefaults:\n project-path: .\n integration: agents\n source: existing _hirmos/ in the project, otherwise the latest GitHub release\n version: latest\n\nNotes:\n --source installs from a local _hirmos folder, framework folder, or hirmos-framework.zip.\n --version selects a GitHub release when _hirmos/ is missing and --source is not provided.\n --offline disables remote release download and requires an existing _hirmos/ or --source.\n\nThis CLI implements hirmos init. Workflow commands such as hirmos requirements are interpreted by an agent after HIRMOS Core is loaded.\n`;
104
+ return `HIRMOS CLI
105
+
106
+ Usage:
107
+ hirmos init [project-path] [--integration <ids>] [--source <path>] [--version <version>] [--offline]
108
+
109
+ Defaults:
110
+ project-path: .
111
+ integration: agents
112
+ source: existing _hirmos/ in the project, otherwise the latest GitHub release
113
+ version: latest
114
+
115
+ Notes:
116
+ hirmos init installs the HIRMOS framework payload when needed and writes selected AI-tool integration files.
117
+ --integration accepts comma-separated ids, for example: agents,claude,cursor,copilot,codex,opencode,gemini,windsurf,kiro.
118
+ --source installs from a local _hirmos folder, framework folder, or hirmos-framework.zip.
119
+ --version selects a GitHub release when _hirmos/ is missing and --source is not provided.
120
+ --offline disables remote release download and requires an existing _hirmos/ or --source.
121
+
122
+ Framework workflow commands such as hirmos start, hirmos status, hirmos continue, and hirmos close are used inside supported AI tools after init, not as terminal CLI commands.
123
+ `;
105
124
  }
@@ -3,14 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_INTERACTION_MODE = exports.INTERACTION_MODES = void 0;
6
7
  exports.loadProjectConfig = loadProjectConfig;
7
8
  exports.mergeProjectConfig = mergeProjectConfig;
9
+ exports.resolveInteractionMode = resolveInteractionMode;
8
10
  exports.writeProjectConfig = writeProjectConfig;
9
11
  const path_1 = __importDefault(require("path"));
10
12
  const filesystem_1 = require("./filesystem");
11
13
  const integration_registry_1 = require("./integration-registry");
14
+ exports.INTERACTION_MODES = [
15
+ "domain_expert",
16
+ "technical_supervisor",
17
+ "framework_dogfooding",
18
+ ];
19
+ exports.DEFAULT_INTERACTION_MODE = "domain_expert";
12
20
  function loadProjectConfig(projectRoot) {
13
- return (0, filesystem_1.readJson)(path_1.default.join(projectRoot, "_hirmos", "project.json"), "_hirmos/project.json");
21
+ return (0, filesystem_1.readJson)(path_1.default.join(projectRoot, "_hirmos", "hirmos.config.json"), "_hirmos/hirmos.config.json");
14
22
  }
15
23
  function mergeProjectConfig(config, selected, registry) {
16
24
  const previousInstalled = Array.isArray(config.integrations?.installed)
@@ -40,6 +48,19 @@ function mergeProjectConfig(config, selected, registry) {
40
48
  wasFirstInitialization: previousInstalled.length === 0
41
49
  };
42
50
  }
51
+ function resolveInteractionMode(config) {
52
+ const raw = config.interaction_mode;
53
+ if (raw === undefined || raw === null || raw === "")
54
+ return exports.DEFAULT_INTERACTION_MODE;
55
+ if (typeof raw !== "string") {
56
+ throw new Error("_hirmos/hirmos.config.json#interaction_mode must be a string when present.");
57
+ }
58
+ const normalized = raw.trim();
59
+ if (exports.INTERACTION_MODES.includes(normalized)) {
60
+ return normalized;
61
+ }
62
+ throw new Error(`_hirmos/hirmos.config.json#interaction_mode must be one of: ${exports.INTERACTION_MODES.join(", ")}. Got: ${raw}`);
63
+ }
43
64
  function writeProjectConfig(projectRoot, config) {
44
- (0, filesystem_1.writeJson)(path_1.default.join(projectRoot, "_hirmos", "project.json"), config);
65
+ (0, filesystem_1.writeJson)(path_1.default.join(projectRoot, "_hirmos", "hirmos.config.json"), config);
45
66
  }
@@ -78,7 +78,8 @@ function installFromDirectory(projectRoot, sourceDir) {
78
78
  if (!(0, filesystem_1.pathExists)(sourceHirmos) || !fs_1.default.statSync(sourceHirmos).isDirectory()) {
79
79
  (0, errors_1.fail)(`Source folder does not contain _hirmos/: ${sourceDir}`);
80
80
  }
81
- copyHirmos(projectRoot, sourceHirmos);
81
+ const sourceReadme = resolveSourceReadmeForDirectory(sourceDir);
82
+ copyHirmos(projectRoot, sourceHirmos, sourceReadme);
82
83
  }
83
84
  function installFromZip(projectRoot, zipPath) {
84
85
  const tmp = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "hirmos-cli-"));
@@ -93,7 +94,8 @@ function installFromZip(projectRoot, zipPath) {
93
94
  if (!sourceHirmos) {
94
95
  (0, errors_1.fail)(`Framework zip does not contain an _hirmos/ folder: ${zipPath}`);
95
96
  }
96
- copyHirmos(projectRoot, sourceHirmos);
97
+ const sourceReadme = resolveSourceReadmeForZip(tmp, sourceHirmos);
98
+ copyHirmos(projectRoot, sourceHirmos, sourceReadme);
97
99
  }
98
100
  finally {
99
101
  fs_1.default.rmSync(tmp, { recursive: true, force: true });
@@ -113,23 +115,57 @@ function findHirmosDir(root) {
113
115
  }
114
116
  return null;
115
117
  }
116
- function copyHirmos(projectRoot, sourceHirmos) {
118
+ function resolveSourceReadmeForDirectory(sourceDir) {
119
+ if (path_1.default.basename(sourceDir) === "_hirmos") {
120
+ return null;
121
+ }
122
+ const repoReadme = path_1.default.join(sourceDir, "README.md");
123
+ if ((0, filesystem_1.pathExists)(repoReadme))
124
+ return repoReadme;
125
+ return null;
126
+ }
127
+ function resolveSourceReadmeForZip(extractRoot, sourceHirmos) {
128
+ const parentReadme = path_1.default.join(path_1.default.dirname(sourceHirmos), "README.md");
129
+ if ((0, filesystem_1.pathExists)(parentReadme))
130
+ return parentReadme;
131
+ const direct = path_1.default.join(extractRoot, "README.md");
132
+ if ((0, filesystem_1.pathExists)(direct))
133
+ return direct;
134
+ return null;
135
+ }
136
+ function copyHirmos(projectRoot, sourceHirmos, sourceReadme = null) {
117
137
  const target = path_1.default.join(projectRoot, "_hirmos");
118
138
  if ((0, filesystem_1.pathExists)(target)) {
119
139
  (0, errors_1.fail)(`Refusing to overwrite existing _hirmos/: ${target}`);
120
140
  }
121
141
  (0, filesystem_1.ensureDir)(projectRoot);
122
142
  fs_1.default.cpSync(sourceHirmos, target, { recursive: true, errorOnExist: true });
143
+ if (sourceReadme && (0, filesystem_1.pathExists)(sourceReadme)) {
144
+ const readmeBody = fs_1.default.readFileSync(sourceReadme, "utf8");
145
+ fs_1.default.writeFileSync(path_1.default.join(target, "README.md"), normalizeReadmeForInstalledHirmos(readmeBody), "utf8");
146
+ }
123
147
  validateCopiedHirmos(projectRoot);
124
148
  }
149
+ function normalizeReadmeForInstalledHirmos(readmeBody) {
150
+ return readmeBody
151
+ .replace(/\(\.\/_hirmos\//gu, "(./")
152
+ .replace(/\(_hirmos\//gu, "(./");
153
+ }
125
154
  function validateCopiedHirmos(projectRoot) {
126
- const required = ["_hirmos/HIRMOS_CORE.md", "_hirmos/VERSION", "_hirmos/project.json"];
155
+ const required = ["_hirmos/AGENTS.md", "_hirmos/README.md", "_hirmos/hirmos.config.json", "_hirmos/core/bootstrap.md", "_hirmos/inputs/README.md", "_hirmos/inputs/uploads/README.md"];
127
156
  for (const relative of required) {
128
157
  if (!(0, filesystem_1.pathExists)(path_1.default.join(projectRoot, relative))) {
129
158
  fs_1.default.rmSync(path_1.default.join(projectRoot, "_hirmos"), { recursive: true, force: true });
130
159
  (0, errors_1.fail)(`Installed framework is incomplete; missing ${relative}. Removed partial _hirmos/ install.`);
131
160
  }
132
161
  }
162
+ const installedReadme = fs_1.default.readFileSync(path_1.default.join(projectRoot, "_hirmos", "README.md"), "utf8");
163
+ for (const phrase of ["Why HIRMOS exists", "Simple by default", "hirmos start", "Understand System State"]) {
164
+ if (!installedReadme.includes(phrase)) {
165
+ fs_1.default.rmSync(path_1.default.join(projectRoot, "_hirmos"), { recursive: true, force: true });
166
+ (0, errors_1.fail)(`Installed framework README is incomplete; missing onboarding phrase: ${phrase}. Removed partial _hirmos/ install.`);
167
+ }
168
+ }
133
169
  }
134
170
  function extractZip(zipPath, destination) {
135
171
  if (process.platform === "win32") {
@@ -19,9 +19,12 @@ function validateProjectRoot(projectRoot) {
19
19
  }
20
20
  function validateHirmosFramework(projectRoot) {
21
21
  const required = [
22
- "_hirmos/HIRMOS_CORE.md",
23
- "_hirmos/project.json",
24
- "_hirmos/integrations/agent-tools/registry.json"
22
+ "_hirmos/AGENTS.md",
23
+ "_hirmos/README.md",
24
+ "_hirmos/hirmos.config.json",
25
+ "_hirmos/integrations/agent-tools/registry.json",
26
+ "_hirmos/inputs/README.md",
27
+ "_hirmos/inputs/uploads/README.md"
25
28
  ];
26
29
  for (const relative of required) {
27
30
  const absolute = path_1.default.join(projectRoot, relative);
@@ -29,6 +32,13 @@ function validateHirmosFramework(projectRoot) {
29
32
  (0, errors_1.fail)(`Required HIRMOS file is missing: ${relative}`);
30
33
  }
31
34
  }
35
+ const readmePath = path_1.default.join(projectRoot, "_hirmos", "README.md");
36
+ const readmeBody = fs_1.default.readFileSync(readmePath, "utf8");
37
+ for (const phrase of ["Why HIRMOS exists", "Simple by default", "hirmos start", "Understand System State"]) {
38
+ if (!readmeBody.includes(phrase)) {
39
+ (0, errors_1.fail)(`Installed HIRMOS README is missing onboarding phrase: ${phrase}`);
40
+ }
41
+ }
32
42
  const templatesDir = path_1.default.join(projectRoot, "_hirmos", "integrations/agent-tools", "templates");
33
43
  if (!(0, filesystem_1.pathExists)(templatesDir) || !fs_1.default.statSync(templatesDir).isDirectory()) {
34
44
  (0, errors_1.fail)("Required HIRMOS directory is missing: _hirmos/integrations/agent-tools/templates/");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hirmos",
3
- "version": "1.3.2",
4
- "description": "HIRMOS product-facing CLI.",
3
+ "version": "1.3.4",
4
+ "description": "HIRMOS framework installer and AI-tool integration CLI.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "commonjs",
7
7
  "bin": {