@curdx/flow 2.3.0 → 2.3.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.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Claude Code Discipline Layer — spec-driven workflow + goal-backward verification + Karpathy 4 principles enforced via gates. Stops Claude from faking \"done\" on non-trivial features.",
9
- "version": "2.3.0"
9
+ "version": "2.3.1"
10
10
  },
11
11
  "allowCrossMarketplaceDependenciesOn": [
12
12
  "context7-marketplace"
@@ -16,7 +16,7 @@
16
16
  "name": "curdx-flow",
17
17
  "source": "./",
18
18
  "description": "Claude Code Discipline Layer — spec-driven workflow + goal-backward verification + Karpathy 4 principles enforced via gates. Stops Claude from faking \"done\" on non-trivial features.",
19
- "version": "2.3.0",
19
+ "version": "2.3.1",
20
20
  "author": {
21
21
  "name": "wdx",
22
22
  "email": "bydongxin@gmail.com"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "curdx-flow",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "description": "Claude Code Discipline Layer — spec-driven workflow + goal-backward verification + Karpathy 4 principles enforced via gates. Stops Claude from faking \"done\" on non-trivial features.",
5
5
  "author": {
6
6
  "name": "wdx",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.3.1
4
+
5
+ - expanded `doctor` to report CurDX-Flow’s bundled main-thread agent, monitor surface, and plugin option defaults
6
+ - documented where Claude Code stores CurDX-Flow non-sensitive `userConfig` values in `pluginConfigs`
7
+ - added troubleshooting guidance for stop-hook blocking and plugin monitor behavior
8
+
3
9
  ## 2.3.0
4
10
 
5
11
  - added a default `flow-orchestrator` main-thread agent through plugin-level `settings.json`
package/README.md CHANGED
@@ -22,6 +22,10 @@ Requires modern Claude Code and Node 18+. The install flow registers the plugin,
22
22
  required reasoning/doc tools, and recommended companion plugins. Run
23
23
  `npx @curdx/flow doctor` after install if anything looks off.
24
24
 
25
+ After restart, CurDX-Flow routes the main thread through `flow-orchestrator`
26
+ by default and starts the bundled `.flow` progress monitor in interactive
27
+ Claude Code sessions.
28
+
25
29
  ## 11 slash commands, that's it
26
30
 
27
31
  ```text
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
3
4
 
4
5
  import { readProjectClaudeSettings } from "./lib/doctor-claude-settings.js";
5
6
  import { inspectRuntimeEnvironment } from "./lib/doctor-runtime-environment.js";
@@ -19,6 +20,8 @@ import {
19
20
  export { readProjectClaudeSettings };
20
21
  export { inspectRuntimeEnvironment };
21
22
 
23
+ const PACKAGE_ROOT = fileURLToPath(new URL("../", import.meta.url));
24
+
22
25
  export function createDoctorContext(args = []) {
23
26
  return {
24
27
  fix: args.includes("--fix"),
@@ -150,6 +153,78 @@ export async function readProjectTeamConfig(cwd = process.cwd()) {
150
153
  return state;
151
154
  }
152
155
 
156
+ export async function readBundledPluginRuntimeDefaults(packageRoot = PACKAGE_ROOT) {
157
+ const pluginSettingsPath = path.join(packageRoot, "settings.json");
158
+ const pluginManifestPath = path.join(packageRoot, ".claude-plugin", "plugin.json");
159
+ const monitorsPath = path.join(packageRoot, "monitors", "monitors.json");
160
+
161
+ const state = {
162
+ exists: false,
163
+ defaultAgent: null,
164
+ subagentStatusLineCommand: null,
165
+ monitorCount: 0,
166
+ monitors: [],
167
+ userConfig: [],
168
+ };
169
+
170
+ let pluginSettings = null;
171
+ let pluginManifest = null;
172
+ let monitors = null;
173
+
174
+ try {
175
+ pluginSettings = JSON.parse(await fs.readFile(pluginSettingsPath, "utf-8"));
176
+ } catch {
177
+ pluginSettings = null;
178
+ }
179
+
180
+ try {
181
+ pluginManifest = JSON.parse(await fs.readFile(pluginManifestPath, "utf-8"));
182
+ } catch {
183
+ pluginManifest = null;
184
+ }
185
+
186
+ try {
187
+ monitors = JSON.parse(await fs.readFile(monitorsPath, "utf-8"));
188
+ } catch {
189
+ monitors = null;
190
+ }
191
+
192
+ if (!pluginSettings && !pluginManifest && !monitors) {
193
+ return state;
194
+ }
195
+
196
+ state.exists = true;
197
+ state.defaultAgent = typeof pluginSettings?.agent === "string" ? pluginSettings.agent : null;
198
+ state.subagentStatusLineCommand =
199
+ typeof pluginSettings?.subagentStatusLine?.command === "string"
200
+ ? pluginSettings.subagentStatusLine.command
201
+ : null;
202
+
203
+ if (Array.isArray(monitors)) {
204
+ state.monitorCount = monitors.length;
205
+ state.monitors = monitors
206
+ .filter((entry) => entry && typeof entry === "object")
207
+ .map((entry) => ({
208
+ name: typeof entry.name === "string" ? entry.name : null,
209
+ when: typeof entry.when === "string" ? entry.when : "always",
210
+ }))
211
+ .filter((entry) => entry.name);
212
+ }
213
+
214
+ if (pluginManifest?.userConfig && typeof pluginManifest.userConfig === "object") {
215
+ state.userConfig = Object.entries(pluginManifest.userConfig)
216
+ .filter(([, value]) => value && typeof value === "object" && !Array.isArray(value))
217
+ .map(([key, value]) => ({
218
+ key,
219
+ type: value.type ?? null,
220
+ default: Object.prototype.hasOwnProperty.call(value, "default") ? value.default : undefined,
221
+ sensitive: value.sensitive === true,
222
+ }));
223
+ }
224
+
225
+ return state;
226
+ }
227
+
153
228
  export async function readProjectState(cwd = process.cwd()) {
154
229
  const flowDir = path.join(cwd, ".flow");
155
230
  try {
@@ -185,6 +260,7 @@ export async function collectDoctorData(
185
260
  readProjectMcpConfigImpl = readProjectMcpConfig,
186
261
  readProjectTeamConfigImpl = readProjectTeamConfig,
187
262
  readProjectClaudeSettingsImpl = readProjectClaudeSettings,
263
+ readBundledPluginRuntimeDefaultsImpl = readBundledPluginRuntimeDefaults,
188
264
  } = {}
189
265
  ) {
190
266
  const claudeVersionValue = claudeVersionImpl();
@@ -212,6 +288,7 @@ export async function collectDoctorData(
212
288
  projectMcpConfig: await readProjectMcpConfigImpl(cwd),
213
289
  projectTeamConfig: await readProjectTeamConfigImpl(cwd),
214
290
  projectClaudeSettings: await readProjectClaudeSettingsImpl(cwd),
291
+ bundledPluginRuntimeDefaults: await readBundledPluginRuntimeDefaultsImpl(),
215
292
  };
216
293
  }
217
294
 
@@ -11,6 +11,8 @@ export function printNextSteps() {
11
11
  console.log(`${color.bold("Next steps")}:\n`);
12
12
  console.log(` ${color.dim("# Verify health")}`);
13
13
  console.log(` ${cliCmd} doctor\n`);
14
+ console.log(` ${color.dim("# Review the bundled main-agent / monitor defaults")}`);
15
+ console.log(` ${color.dim("# (doctor now prints CurDX-Flow runtime defaults and plugin option keys)")}\n`);
14
16
  console.log(` ${color.dim("# Inside any project, initialize and start a feature spec")}`);
15
17
  console.log(` ${color.cyan("cd ~/your-project")}`);
16
18
  console.log(` ${color.cyan("claude")}`);
@@ -130,6 +130,7 @@ export function buildDoctorReport({
130
130
  projectMcpConfig,
131
131
  projectTeamConfig,
132
132
  projectClaudeSettings,
133
+ bundledPluginRuntimeDefaults,
133
134
  }) {
134
135
  const lines = [];
135
136
  const sections = [];
@@ -345,6 +346,63 @@ export function buildDoctorReport({
345
346
  }
346
347
  }
347
348
 
349
+ if (bundledPluginRuntimeDefaults?.exists) {
350
+ const bundledRuntimeSection = createSection("CurDX-Flow bundled runtime:");
351
+
352
+ if (bundledPluginRuntimeDefaults.defaultAgent) {
353
+ pushSectionLine(
354
+ bundledRuntimeSection,
355
+ "ok",
356
+ `Main thread agent ${bundledPluginRuntimeDefaults.defaultAgent}`,
357
+ [
358
+ "plugin-level settings route the main Claude thread through this agent by default",
359
+ ]
360
+ );
361
+ }
362
+
363
+ if (bundledPluginRuntimeDefaults.subagentStatusLineCommand) {
364
+ pushSectionLine(
365
+ bundledRuntimeSection,
366
+ "info",
367
+ `Subagent status line configured`,
368
+ [bundledPluginRuntimeDefaults.subagentStatusLineCommand]
369
+ );
370
+ }
371
+
372
+ if (bundledPluginRuntimeDefaults.monitorCount > 0) {
373
+ const monitorSummary = bundledPluginRuntimeDefaults.monitors
374
+ .map((monitor) => `${monitor.name} (${monitor.when})`)
375
+ .join(", ");
376
+ pushSectionLine(
377
+ bundledRuntimeSection,
378
+ "ok",
379
+ `Plugin monitors ${bundledPluginRuntimeDefaults.monitorCount} configured`,
380
+ [
381
+ monitorSummary,
382
+ "official docs: plugin monitors run only in interactive Claude Code sessions where the Monitor tool is available",
383
+ ]
384
+ );
385
+ }
386
+
387
+ if ((bundledPluginRuntimeDefaults.userConfig || []).length > 0) {
388
+ const optionSummary = bundledPluginRuntimeDefaults.userConfig
389
+ .map((option) => {
390
+ const suffix = option.default === undefined ? "" : `=${String(option.default)}`;
391
+ return `${option.key}${suffix}`;
392
+ })
393
+ .join(", ");
394
+ pushSectionLine(
395
+ bundledRuntimeSection,
396
+ "info",
397
+ `Plugin options ${bundledPluginRuntimeDefaults.userConfig.length} available`,
398
+ [
399
+ optionSummary,
400
+ "non-sensitive values are stored under pluginConfigs[curdx-flow@curdx-flow-marketplace].options in Claude settings.json",
401
+ ]
402
+ );
403
+ }
404
+ }
405
+
348
406
  const localProjectSection = createSection("Local project:");
349
407
  if (projectState?.exists) {
350
408
  pushSectionLine(localProjectSection, "ok", `.flow/ ${cwd}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curdx/flow",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "description": "Skill-first discipline layer and CLI installer for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {