@flowmind/cli 0.2.0 → 0.2.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.
- package/README.md +5 -1
- package/dist/flowmind/SKILL.md +1 -0
- package/dist/index.js +29 -18
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -13,7 +13,11 @@ flowmind hooks install
|
|
|
13
13
|
|
|
14
14
|
`hooks install` copies the Flowmind skill to Codex and Claude Code and adds session hooks to
|
|
15
15
|
`~/.codex/hooks.json` and `~/.claude/settings.json`. Other hooks in those files stay as they are.
|
|
16
|
-
The hooks run `
|
|
16
|
+
The hooks run `agent hook` through the absolute paths of the installing Node binary and CLI file,
|
|
17
|
+
because hooks start without your shell profile and a version manager may not put `node` on PATH.
|
|
18
|
+
Codex on Windows gets a PowerShell command (`& '<node>' '<cli>' agent hook --agent codex`).
|
|
19
|
+
After you upgrade Node or move the CLI, `hooks status` shows `outdated`; run `hooks install` again
|
|
20
|
+
and trust the changed hooks. The hook records each agent turn under the CLI config folder.
|
|
17
21
|
In a linked repository, the session-start hook tells the agent which project it works on.
|
|
18
22
|
Codex runs new hooks only after you trust them once in `/hooks`. `hooks status` shows both installs,
|
|
19
23
|
and `hooks uninstall` removes only the Flowmind entries.
|
package/dist/flowmind/SKILL.md
CHANGED
|
@@ -63,6 +63,7 @@ Ask only for missing fields. A natural-language entry (`flowmind log "2h on the
|
|
|
63
63
|
|
|
64
64
|
- `flowmind auth status` shows the API URL. A normal install uses `https://api.flowmind.pro`.
|
|
65
65
|
- `flowmind hooks status` shows whether the skill and hooks are installed for Codex and Claude Code.
|
|
66
|
+
- `outdated` hooks: run `flowmind hooks install` again (for example after a Node upgrade) and trust the changed hooks.
|
|
66
67
|
- "No recorded agent time": the hooks are missing or not trusted, or the session started before installation. Stage with observed `--minutes` and `--started-at`, or stage in the next session.
|
|
67
68
|
- "Several agent sessions have a turn in progress": pass `--session-id`.
|
|
68
69
|
- "No project given": run `flowmind link <project>` in the repository, or pass `--project`.
|
package/dist/index.js
CHANGED
|
@@ -3440,9 +3440,11 @@ var logCommand = new Command3("log").description("Log time with natural language
|
|
|
3440
3440
|
|
|
3441
3441
|
// src/commands/hooks.ts
|
|
3442
3442
|
import { createHash as createHash3 } from "node:crypto";
|
|
3443
|
+
import { realpathSync } from "node:fs";
|
|
3443
3444
|
import { readFile as readFile3, lstat, mkdir as mkdir2, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
3444
3445
|
import { homedir } from "node:os";
|
|
3445
3446
|
import { dirname as dirname3, join as join3 } from "node:path";
|
|
3447
|
+
import { fileURLToPath } from "node:url";
|
|
3446
3448
|
import { Command as Command4, InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
3447
3449
|
var agents = ["codex", "claude"];
|
|
3448
3450
|
var installedHashFile = ".flowmind-installed.sha256";
|
|
@@ -3477,31 +3479,40 @@ async function inspect(agent) {
|
|
|
3477
3479
|
}
|
|
3478
3480
|
return { state: savedHash === contentHash ? "installed" : "modified", path, markerPath, contentHash };
|
|
3479
3481
|
}
|
|
3480
|
-
var
|
|
3482
|
+
var FLOWMIND_HOOK = /(?:^flowmind|index\.js') agent hook --agent (?:codex|claude)$/;
|
|
3483
|
+
var portablePath = (path) => realpathSync(path).replaceAll("\\", "/");
|
|
3484
|
+
function hookCommand(agent) {
|
|
3485
|
+
const node = portablePath(process.execPath);
|
|
3486
|
+
const cli = portablePath(fileURLToPath(import.meta.url));
|
|
3487
|
+
const args = `agent hook --agent ${agent}`;
|
|
3488
|
+
if (process.platform === "win32" && agent === "codex") {
|
|
3489
|
+
const quote2 = (value) => `'${value.replaceAll("'", "''")}'`;
|
|
3490
|
+
return `& ${quote2(node)} ${quote2(cli)} ${args}`;
|
|
3491
|
+
}
|
|
3492
|
+
const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
3493
|
+
return `${quote(node)} ${quote(cli)} ${args}`;
|
|
3494
|
+
}
|
|
3481
3495
|
var handler = (agent, timeout, background = false) => ({
|
|
3482
3496
|
type: "command",
|
|
3483
|
-
command:
|
|
3497
|
+
command: hookCommand(agent),
|
|
3484
3498
|
timeout,
|
|
3485
3499
|
...background ? { async: true } : {}
|
|
3486
3500
|
});
|
|
3487
|
-
var hookEvents = {
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
},
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
UserPromptSubmit: { hooks: [handler("claude", 10)] },
|
|
3497
|
-
Stop: { hooks: [handler("claude", 10)] }
|
|
3498
|
-
}
|
|
3501
|
+
var hookEvents = (agent) => agent === "codex" ? {
|
|
3502
|
+
SessionStart: { hooks: [handler("codex", 10)] },
|
|
3503
|
+
UserPromptSubmit: { hooks: [handler("codex", 10, true)] },
|
|
3504
|
+
Stop: { hooks: [handler("codex", 10)] },
|
|
3505
|
+
Interrupt: { hooks: [handler("codex", 3)] }
|
|
3506
|
+
} : {
|
|
3507
|
+
SessionStart: { hooks: [handler("claude", 10)] },
|
|
3508
|
+
UserPromptSubmit: { hooks: [handler("claude", 10)] },
|
|
3509
|
+
Stop: { hooks: [handler("claude", 10)] }
|
|
3499
3510
|
};
|
|
3500
3511
|
function hookConfigPath(agent) {
|
|
3501
3512
|
return agent === "codex" ? join3(homedir(), ".codex", "hooks.json") : join3(homedir(), ".claude", "settings.json");
|
|
3502
3513
|
}
|
|
3503
3514
|
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3504
|
-
var isFlowmindGroup = (group) => isObject(group) && Array.isArray(group.hooks) && group.hooks.length > 0 && group.hooks.every((hook) => isObject(hook) && typeof hook.command === "string" && hook.command
|
|
3515
|
+
var isFlowmindGroup = (group) => isObject(group) && Array.isArray(group.hooks) && group.hooks.length > 0 && group.hooks.every((hook) => isObject(hook) && typeof hook.command === "string" && FLOWMIND_HOOK.test(hook.command));
|
|
3505
3516
|
async function readHookConfig(agent) {
|
|
3506
3517
|
const path = hookConfigPath(agent);
|
|
3507
3518
|
let text;
|
|
@@ -3532,7 +3543,7 @@ function hookState(config2, agent) {
|
|
|
3532
3543
|
([event, groups]) => groups.filter(isFlowmindGroup).map((group) => `${event}:${JSON.stringify(group)}`)
|
|
3533
3544
|
);
|
|
3534
3545
|
if (ours.length === 0) return "absent";
|
|
3535
|
-
const expected = Object.entries(hookEvents
|
|
3546
|
+
const expected = Object.entries(hookEvents(agent)).map(([event, group]) => `${event}:${JSON.stringify(group)}`);
|
|
3536
3547
|
const exact = ours.length === expected.length && expected.every((entry) => ours.includes(entry));
|
|
3537
3548
|
return exact ? "installed" : "outdated";
|
|
3538
3549
|
}
|
|
@@ -3551,7 +3562,7 @@ function withoutFlowmindHooks(config2) {
|
|
|
3551
3562
|
function withFlowmindHooks(config2, agent) {
|
|
3552
3563
|
const next = withoutFlowmindHooks(config2);
|
|
3553
3564
|
const hooks = isObject(next.hooks) ? { ...next.hooks } : {};
|
|
3554
|
-
for (const [event, group] of Object.entries(hookEvents
|
|
3565
|
+
for (const [event, group] of Object.entries(hookEvents(agent))) {
|
|
3555
3566
|
hooks[event] = [...hooks[event] ?? [], group];
|
|
3556
3567
|
}
|
|
3557
3568
|
return { ...next, hooks };
|
|
@@ -5258,7 +5269,7 @@ var shipLogCommand = new Command10("ship-log").description("Read a project ship
|
|
|
5258
5269
|
|
|
5259
5270
|
// src/index.ts
|
|
5260
5271
|
var program = new Command11();
|
|
5261
|
-
program.name("flowmind").description("Flowmind CLI (also installed as fm)").version("0.2.
|
|
5272
|
+
program.name("flowmind").description("Flowmind CLI (also installed as fm)").version("0.2.1").enablePositionalOptions();
|
|
5262
5273
|
program.addCommand(agentCommand);
|
|
5263
5274
|
program.addCommand(authCommand);
|
|
5264
5275
|
program.addCommand(logCommand);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowmind/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "CLI for Flowmind — proof-of-effort hour ledger",
|
|
5
5
|
"homepage": "https://www.flowmind.pro",
|
|
6
6
|
"repository": {
|
|
@@ -14,10 +14,13 @@
|
|
|
14
14
|
"publishConfig": {
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|
|
17
|
-
"files": [
|
|
17
|
+
"files": [
|
|
18
|
+
"dist/index.js",
|
|
19
|
+
"dist/flowmind/SKILL.md"
|
|
20
|
+
],
|
|
18
21
|
"bin": {
|
|
19
|
-
"fm": "
|
|
20
|
-
"flowmind": "
|
|
22
|
+
"fm": "dist/index.js",
|
|
23
|
+
"flowmind": "dist/index.js"
|
|
21
24
|
},
|
|
22
25
|
"type": "module",
|
|
23
26
|
"scripts": {
|