@planu/cli 4.3.3 → 4.3.5

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/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## [4.3.5] - 2026-05-24
2
+
3
+ ### Features
4
+ - feat(codegraph): expose Colby CodeGraph setup and status tools on the official MCP surface
5
+
6
+ ### Bug Fixes
7
+ - fix(create-spec): render structured post-creation suggestions as readable next steps
8
+ - fix(mcp): guard malformed human-facing tool output before it reaches clients
9
+
10
+
11
+ ## [4.3.4] - 2026-05-22
12
+
13
+ **Tarball SHA-256:** `e1ac042fd623c1421d7a0788fed14c369472489180ffe80eb8bce4d422d360d8`
14
+
15
+ ### Bug Fixes
16
+ - fix(planu): keep host adapters outside managed state
17
+
18
+
1
19
  ## [4.3.3] - 2026-05-22
2
20
 
3
21
  **Tarball SHA-256:** `d681d7d176a263f3b059c4ed5fbc7647a17758dc3c56cc79fd47658bab082fe6`
@@ -3930,4 +3948,4 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning:
3930
3948
  - Mermaid diagram generation (architecture, sequence, state machine, ER, data flow)
3931
3949
  - Multi-language i18n (EN/ES/PT) for generated specs
3932
3950
  - Clean Architecture (hexagonal) — engine, tools, storage, types layers
3933
- - 10,857 tests with ≥95% coverage
3951
+ - 10,857 tests with ≥95% coverage
@@ -42,12 +42,14 @@
42
42
  "check_update_status",
43
43
  "check_versions",
44
44
  "clarify_requirements",
45
+ "code_graph_status",
45
46
  "compliance_coverage_report",
46
47
  "compliance_gap_analysis",
47
48
  "compliance_gate_status",
48
49
  "compliance_score_report",
49
50
  "config_health",
50
51
  "configure_approval_policy",
52
+ "configure_code_graph",
51
53
  "configure_compliance",
52
54
  "configure_deploy_target",
53
55
  "configure_memory",
@@ -19,5 +19,5 @@ export declare function buildStatusResult(config: ClaudeJsonConfig): CodeGraphSt
19
19
  /**
20
20
  * Return the key used in .claude.json for a given action.
21
21
  */
22
- export declare function actionToProviderKey(action: 'setup-codegraph-context' | 'setup-pathfinder' | 'setup-axon'): string;
22
+ export declare function actionToProviderKey(action: 'setup-colby-codegraph' | 'setup-codegraph-context' | 'setup-pathfinder' | 'setup-axon'): string;
23
23
  //# sourceMappingURL=code-graph-configurator.d.ts.map
@@ -2,6 +2,12 @@
2
2
  // Provider definitions
3
3
  // ---------------------------------------------------------------------------
4
4
  const PROVIDER_DEFS = [
5
+ {
6
+ key: 'codegraph',
7
+ provider: 'colby-codegraph',
8
+ command: 'npx',
9
+ args: ['-y', '@colbymchenry/codegraph', 'serve', '--mcp'],
10
+ },
5
11
  {
6
12
  key: 'codegraphcontext',
7
13
  provider: 'codegraph-context',
@@ -71,6 +77,7 @@ export function buildStatusResult(config) {
71
77
  */
72
78
  export function actionToProviderKey(action) {
73
79
  const map = {
80
+ 'setup-colby-codegraph': 'codegraph',
74
81
  'setup-codegraph-context': 'codegraphcontext',
75
82
  'setup-pathfinder': 'code-pathfinder',
76
83
  'setup-axon': 'axon',
@@ -4,6 +4,7 @@ export const PLANU_CANONICAL_POLICY = {
4
4
  canonicalRootFiles: ['conventions.json', 'context.md', 'session-context.md', 'session.json'],
5
5
  canonicalRootDirs: ['releases', 'specs'],
6
6
  canonicalSpecFiles: ['spec.md'],
7
+ forbiddenHostAssetRootDirs: ['agents', 'skills', 'rules', 'hooks'],
7
8
  generatedRuntimePatterns: [
8
9
  'planu/index.html',
9
10
  'planu/roadmap.html',
@@ -57,6 +58,12 @@ export function canonicalContractText() {
57
58
  ' specs/',
58
59
  ' SPEC-XXX-slug/',
59
60
  ' spec.md',
61
+ '',
62
+ 'Host adapters are written outside planu/:',
63
+ ' Claude Code: .claude/agents, .claude/skills, .claude/rules',
64
+ ' Codex: AGENTS.md, .agents/skills, .codex/agents',
65
+ ' Gemini: GEMINI.md, .gemini/skills',
66
+ ' Cursor: .cursor/rules/planu.mdc',
60
67
  ].join('\n');
61
68
  }
62
69
  //# sourceMappingURL=planu-canonical-policy.js.map
@@ -13,6 +13,7 @@ import { join } from 'node:path';
13
13
  import { detectCodexWorkspace } from './workspace-scope.js';
14
14
  import { buildRulesForHost } from '../../engine/host-rules-templates/index.js';
15
15
  import { assertEnglishOnlyArtifactText } from '../../engine/spec-language/english-only.js';
16
+ import { generateImplementerRole, generateReviewerRole, generateSpecWriterRole, } from '../../engine/ai-integration/codex/agent-roles-generator.js';
16
17
  const CODEX_CONFIG_TOML = `# .openai/config.toml — Planu Codex workspace configuration
17
18
  # Auto-generated by Planu init_project. Safe to customize.
18
19
 
@@ -69,6 +70,7 @@ export async function scaffoldCodexConfig(projectPath, planuVersion = '1.96.0')
69
70
  await mkdir(openaiDir, { recursive: true });
70
71
  await writeIfMissing(join(openaiDir, 'config.toml'), CODEX_CONFIG_TOML);
71
72
  await writeIfMissing(join(projectPath, 'AGENTS.md'), AGENTS_MD_CONTENT);
73
+ await scaffoldCodexAgentRoles(projectPath);
72
74
  await injectRulesBlock(join(projectPath, 'AGENTS.md'), planuVersion);
73
75
  }
74
76
  // ---------------------------------------------------------------------------
@@ -86,6 +88,15 @@ async function writeIfMissing(filePath, content) {
86
88
  await writeFile(filePath, content, 'utf-8');
87
89
  }
88
90
  }
91
+ async function scaffoldCodexAgentRoles(projectPath) {
92
+ const agentsDir = join(projectPath, '.codex', 'agents');
93
+ await mkdir(agentsDir, { recursive: true });
94
+ await Promise.all([
95
+ writeIfMissing(join(agentsDir, 'spec-writer.toml'), generateSpecWriterRole()),
96
+ writeIfMissing(join(agentsDir, 'implementer.toml'), generateImplementerRole()),
97
+ writeIfMissing(join(agentsDir, 'reviewer.toml'), generateReviewerRole()),
98
+ ]);
99
+ }
89
100
  const PLANU_RULES_BLOCK_REGEX = /<!-- planu:rules:start[\s\S]*?<!-- planu:rules:end -->/;
90
101
  const PLANU_RULES_START_REGEX = /<!-- planu:rules:start[^>]* -->/;
91
102
  /**
@@ -43,6 +43,10 @@ export async function handleConfigureCodeGraph(input) {
43
43
  JSON.stringify({ [providerKey]: entry }, null, 2),
44
44
  '```',
45
45
  '',
46
+ providerKey === 'codegraph'
47
+ ? 'Initialize the project index with `npx -y @colbymchenry/codegraph init -i` from the project root before relying on graph queries.'
48
+ : 'Initialize the provider index using the provider documentation before relying on graph queries.',
49
+ '',
46
50
  'Restart Claude Code (or your MCP client) to activate the new server.',
47
51
  ];
48
52
  return { content: [{ type: 'text', text: lines.join('\n') }] };
@@ -11,6 +11,8 @@ export declare function checkContradictions(projectId: string, specId: string, d
11
11
  export declare function fireSpecCreatedHook(projectId: string, spec: Spec, projectPath: string): void;
12
12
  /** Generates post-creation suggestions based on project state and spec description. Best-effort: never throws. */
13
13
  export declare function generatePostCreationSuggestions(projectPath: string, description: string, knowledge?: ProjectKnowledge): Promise<PostCreationSuggestion[]>;
14
+ /** Formats a structured post-creation suggestion for human-readable next steps. */
15
+ export declare function formatPostCreationSuggestion(suggestion: PostCreationSuggestion): string;
14
16
  /**
15
17
  * SPEC-781: Run heavy analysis (contradiction detection, complexity advice) in a
16
18
  * fire-and-forget fashion after the spec has already been persisted synchronously.
@@ -162,6 +162,11 @@ export async function generatePostCreationSuggestions(projectPath, description,
162
162
  });
163
163
  return suggestions;
164
164
  }
165
+ /** Formats a structured post-creation suggestion for human-readable next steps. */
166
+ export function formatPostCreationSuggestion(suggestion) {
167
+ const templateSuffix = suggestion.templateCategory !== undefined ? ` (${suggestion.templateCategory})` : '';
168
+ return `${suggestion.tool}${templateSuffix}: ${suggestion.reason}`;
169
+ }
165
170
  /**
166
171
  * SPEC-781: Run heavy analysis (contradiction detection, complexity advice) in a
167
172
  * fire-and-forget fashion after the spec has already been persisted synchronously.
@@ -10,7 +10,7 @@ import { estimateSpec } from '../engine/estimator.js';
10
10
  import { checkSpecReadiness } from '../engine/readiness-checker.js';
11
11
  import { buildSpecContext, buildSplitResult } from './create-spec/spec-builder.js';
12
12
  import { validateConstitution } from './create-spec/constitution-validator.js';
13
- import { setupGitBranch, checkContradictions, fireSpecCreatedHook, generatePostCreationSuggestions, runAutopilotAsync, getAsyncAnalysisPath, } from './create-spec/post-creation.js';
13
+ import { setupGitBranch, checkContradictions, fireSpecCreatedHook, generatePostCreationSuggestions, formatPostCreationSuggestion, runAutopilotAsync, getAsyncAnalysisPath, } from './create-spec/post-creation.js';
14
14
  import { notifyStoreChange } from '../engine/doc-generator/portal/regen-hook.js';
15
15
  import { compactObj } from '../engine/compact-obj.js';
16
16
  import { buildCreateSpecSummary } from '../engine/human-summary.js';
@@ -894,7 +894,7 @@ export async function handleCreateSpec(inputParams, server) {
894
894
  }
895
895
  // Append auto-pipeline output (SPEC-445)
896
896
  lines.push(...formatPipelineLines(pipelineResult));
897
- const allNextSteps = result.nextSteps ?? [];
897
+ const allNextSteps = (result.nextSteps ?? []).map((step) => (typeof step === 'string' ? step : formatPostCreationSuggestion(step)));
898
898
  const markdownText = allNextSteps.length > 0
899
899
  ? addNextSteps(formatSuccess(ti('tools.create_spec.success', { id: spec.id, title: spec.title }), lines.join('\n')), allNextSteps)
900
900
  : formatSuccess(ti('tools.create_spec.success', { id: spec.id, title: spec.title }), lines.join('\n'));
@@ -88,7 +88,12 @@ export function getTierSync() {
88
88
  // ---------------------------------------------------------------------------
89
89
  const sessionTierCache = new Map();
90
90
  const SESSION_TIER_TTL_MS = 10 * 60 * 1000; // 10 min — longer since online validation is expensive
91
- const RATE_LIMIT_EXEMPT_TOOLS = new Set(['planu_status', 'update_status_batch']);
91
+ const RATE_LIMIT_EXEMPT_TOOLS = new Set([
92
+ 'planu_status',
93
+ 'update_status_batch',
94
+ 'configure_code_graph',
95
+ 'code_graph_status',
96
+ ]);
92
97
  export function shouldBypassDailyRateLimit(toolName) {
93
98
  return RATE_LIMIT_EXEMPT_TOOLS.has(toolName);
94
99
  }
@@ -0,0 +1,11 @@
1
+ import type { ToolResult } from '../types/index.js';
2
+ type MalformedOutputCode = 'OBJECT_OBJECT' | 'OBJECT_PROMISE';
3
+ interface MalformedOutputIssue {
4
+ code: MalformedOutputCode;
5
+ pattern: string;
6
+ contentIndex: number;
7
+ }
8
+ export declare function findMalformedToolOutput(result: ToolResult): MalformedOutputIssue | null;
9
+ export declare function guardToolResultOutput(toolName: string | undefined, result: ToolResult): ToolResult;
10
+ export {};
11
+ //# sourceMappingURL=output-integrity-guard.d.ts.map
@@ -0,0 +1,53 @@
1
+ const MALFORMED_TEXT_PATTERNS = [
2
+ { code: 'OBJECT_OBJECT', pattern: /\[object Object\]/, label: '[object Object]' },
3
+ { code: 'OBJECT_PROMISE', pattern: /\[object Promise\]/, label: '[object Promise]' },
4
+ ];
5
+ export function findMalformedToolOutput(result) {
6
+ for (let index = 0; index < result.content.length; index++) {
7
+ const item = result.content[index];
8
+ const text = item?.text ?? '';
9
+ for (const rule of MALFORMED_TEXT_PATTERNS) {
10
+ if (rule.pattern.test(text)) {
11
+ return {
12
+ code: rule.code,
13
+ pattern: rule.label,
14
+ contentIndex: index,
15
+ };
16
+ }
17
+ }
18
+ }
19
+ return null;
20
+ }
21
+ export function guardToolResultOutput(toolName, result) {
22
+ const issue = findMalformedToolOutput(result);
23
+ if (issue === null) {
24
+ return result;
25
+ }
26
+ const name = toolName ?? 'unknown';
27
+ const structuredKeys = Object.keys(result.structuredContent ?? {});
28
+ return {
29
+ content: [
30
+ {
31
+ type: 'text',
32
+ text: [
33
+ '❌ **Output integrity guard blocked malformed response**',
34
+ '',
35
+ `Tool \`${name}\` produced non-human-readable text (${issue.code}).`,
36
+ 'The operation may have completed before the response was blocked.',
37
+ 'Run `planu_status` or retry the tool after the formatting bug is fixed.',
38
+ ].join('\n'),
39
+ },
40
+ ],
41
+ isError: true,
42
+ structuredContent: {
43
+ error: 'OUTPUT_INTEGRITY_GUARD',
44
+ toolName: name,
45
+ pattern: issue.code,
46
+ contentIndex: issue.contentIndex,
47
+ operationMayHaveCompleted: true,
48
+ originalStructuredContentKeys: structuredKeys,
49
+ fixHint: 'A Planu tool attempted to render a structured object as human text. Format the object explicitly before returning content[].text.',
50
+ },
51
+ };
52
+ }
53
+ //# sourceMappingURL=output-integrity-guard.js.map
@@ -1,4 +1,4 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- export declare const OFFICIAL_SDD_TOOL_NAMES: readonly ["planu_status", "facilitate", "init_project", "clarify_requirements", "create_spec", "challenge_spec", "check_readiness", "update_status", "update_status_batch", "package_handoff", "validate", "reconcile_spec", "create_rule", "create_skill", "skill_search"];
2
+ export declare const OFFICIAL_SDD_TOOL_NAMES: readonly ["planu_status", "facilitate", "init_project", "clarify_requirements", "create_spec", "challenge_spec", "check_readiness", "update_status", "update_status_batch", "package_handoff", "validate", "reconcile_spec", "create_rule", "create_skill", "skill_search", "configure_code_graph", "code_graph_status"];
3
3
  export declare function registerSddTools(server: McpServer): void;
4
4
  //# sourceMappingURL=register-sdd-tools.d.ts.map
@@ -28,6 +28,8 @@ export const OFFICIAL_SDD_TOOL_NAMES = [
28
28
  'create_rule',
29
29
  'create_skill',
30
30
  'skill_search',
31
+ 'configure_code_graph',
32
+ 'code_graph_status',
31
33
  ];
32
34
  const OFFICIAL_SDD_TOOL_SET = new Set(OFFICIAL_SDD_TOOL_NAMES);
33
35
  const noop = () => undefined;
@@ -17,6 +17,7 @@ import { consumeUpdateBanner } from '../engine/update-notifier.js';
17
17
  import { getOrCreateInstallationId } from '../engine/telemetry/telemetry-store.js';
18
18
  import { compressToolOutput } from './output-compressor.js';
19
19
  import { recordToolTokens as recordLlmTokens } from '../engine/llm-runtime/index.js';
20
+ import { guardToolResultOutput } from './output-integrity-guard.js';
20
21
  // SPEC-902: Structured error contract
21
22
  import { wrapError, isStructuredError } from '../engine/errors/error-wrapper.js';
22
23
  import { getErrorRecoveryRegistry } from '../engine/errors/registry-loader.js';
@@ -279,26 +280,27 @@ function safeWithTelemetry(toolName, handler) {
279
280
  content: [...withDrift.content, { type: 'text', text: updateBanner }],
280
281
  }
281
282
  : withDrift;
283
+ const guardedResult = guardToolResultOutput(toolName, finalResult);
282
284
  // Report validation errors (isError:true returned by handler logic, not exceptions)
283
- if (toolName !== undefined && finalResult.isError === true) {
284
- const firstContent = finalResult.content[0];
285
+ if (toolName !== undefined && guardedResult.isError === true) {
286
+ const firstContent = guardedResult.content[0];
285
287
  const errText = firstContent?.type === 'text' ? firstContent.text : 'unknown error';
286
288
  reportToolValidationError(toolName, errText);
287
289
  }
288
290
  // Record token usage for successful calls (fire-and-forget, only when projectPath available)
289
- if (toolName !== undefined && projectPath !== undefined && finalResult.isError !== true) {
290
- const outputText = extractOutputText(finalResult);
291
+ if (toolName !== undefined && projectPath !== undefined && guardedResult.isError !== true) {
292
+ const outputText = extractOutputText(guardedResult);
291
293
  recordToolTokens(toolName, projectPath, args, outputText, SESSION_ID);
292
294
  }
293
295
  // SPEC-460: Track real token estimates in LLM runtime (session-scoped, measured)
294
296
  if (toolName !== undefined) {
295
297
  const inputText = JSON.stringify(args);
296
- const outputText = extractOutputText(finalResult);
298
+ const outputText = extractOutputText(guardedResult);
297
299
  recordLlmTokens(toolName, inputText, outputText);
298
300
  }
299
301
  // Emit tool_used telemetry for successful calls (fire-and-forget)
300
302
  /* v8 ignore start */
301
- if (toolName !== undefined && finalResult.isError !== true && isErrorReportingEnabled()) {
303
+ if (toolName !== undefined && guardedResult.isError !== true && isErrorReportingEnabled()) {
302
304
  getOrCreateInstallationId()
303
305
  .then((installationId) => {
304
306
  sendTelemetryEvent({
@@ -331,7 +333,7 @@ function safeWithTelemetry(toolName, handler) {
331
333
  const partial = buildAuditEntry({
332
334
  toolName,
333
335
  args,
334
- outputType: finalResult.isError === true ? 'error' : 'success',
336
+ outputType: guardedResult.isError === true ? 'error' : 'success',
335
337
  durationMs: Date.now() - startTime,
336
338
  prevHash,
337
339
  });
@@ -344,9 +346,9 @@ function safeWithTelemetry(toolName, handler) {
344
346
  /* v8 ignore stop */
345
347
  // SPEC-563: Auto session checkpoint — fire-and-forget, non-blocking
346
348
  if (toolName !== undefined) {
347
- maybeWriteCheckpoint(toolName, finalResult.isError !== true, projectPath);
349
+ maybeWriteCheckpoint(toolName, guardedResult.isError !== true, projectPath);
348
350
  }
349
- return finalResult;
351
+ return guardedResult;
350
352
  }
351
353
  catch (error) {
352
354
  const message = error instanceof Error ? error.message : String(error);
@@ -71,6 +71,8 @@ import { handleAuditClaudeConfig } from '../audit-claude-config.js';
71
71
  import { handleGenerateDocsSite } from '../generate-docs-site.js';
72
72
  // ── Memory config tools (register-memory-config-tools.ts) ────────────────────
73
73
  import { handleConfigureMemory, handleMemoryStatus } from '../memory-config-handler.js';
74
+ // ── Code graph tools (SPEC-376 / SPEC-1060) ─────────────────────────────────
75
+ import { handleConfigureCodeGraph, handleCodeGraphStatus } from '../code-graph-handler.js';
74
76
  // ── Onboarding tools (register-onboarding-tools.ts) ──────────────────────────
75
77
  import { handleStartOnboarding, handleGuidedTour, handleOnboardingChecklist, handleQuickStart, handleOnboardingProgress, } from '../onboarding-handler.js';
76
78
  // ── Docs registry tools (register-docs-registry-tools.ts) ────────────────────
@@ -827,6 +829,30 @@ export function registerInfraGroupTools(server) {
827
829
  projectPath: z.string().describe('Absolute path to the project root directory'),
828
830
  },
829
831
  }, safeLicensed('memory_status', async (args) => handleMemoryStatus(args)));
832
+ // ── Code graph tools ──────────────────────────────────────────────────────
833
+ server.registerTool('configure_code_graph', {
834
+ description: 'Configure a local code graph MCP provider for the project. Supports Colby CodeGraph, CodeGraphContext, Pathfinder, and Axon. Writes the provider entry to .claude.json.',
835
+ annotations: { title: 'Configure Code Graph', readOnlyHint: false },
836
+ inputSchema: {
837
+ projectPath: z.string().min(1).max(4096).describe('Absolute path to the project root'),
838
+ action: z
839
+ .enum([
840
+ 'setup-colby-codegraph',
841
+ 'setup-codegraph-context',
842
+ 'setup-pathfinder',
843
+ 'setup-axon',
844
+ 'status',
845
+ ])
846
+ .describe('setup-colby-codegraph: configure @colbymchenry/codegraph | setup-codegraph-context: configure CodeGraphContext | setup-pathfinder: configure Pathfinder | setup-axon: configure Axon | status: show current provider status'),
847
+ },
848
+ }, safeLicensed('configure_code_graph', async (args) => handleConfigureCodeGraph(args)));
849
+ server.registerTool('code_graph_status', {
850
+ description: 'Returns the current code graph MCP provider status from .claude.json, including the active provider if one is configured.',
851
+ annotations: { title: 'Code Graph Status', readOnlyHint: true },
852
+ inputSchema: {
853
+ projectPath: z.string().min(1).max(4096).describe('Absolute path to the project root'),
854
+ },
855
+ }, safeLicensed('code_graph_status', async (args) => handleCodeGraphStatus(args)));
830
856
  // ── Onboarding tools ───────────────────────────────────────────────────────
831
857
  server.registerTool('start_onboarding', {
832
858
  description: 'Start interactive onboarding for a new project. Generates personalized recommendations based on your role, project type, and team size. Returns a markdown guide with next steps.',
@@ -1,5 +1,5 @@
1
- export type CodeGraphProvider = 'codegraph-context' | 'pathfinder' | 'axon';
2
- export type CodeGraphAction = 'setup-codegraph-context' | 'setup-pathfinder' | 'setup-axon' | 'status';
1
+ export type CodeGraphProvider = 'colby-codegraph' | 'codegraph-context' | 'pathfinder' | 'axon';
2
+ export type CodeGraphAction = 'setup-colby-codegraph' | 'setup-codegraph-context' | 'setup-pathfinder' | 'setup-axon' | 'status';
3
3
  export interface CodeGraphSetupInput {
4
4
  projectPath: string;
5
5
  action: CodeGraphAction;
@@ -47,6 +47,7 @@ export interface PlanuCanonicalPathPolicy {
47
47
  readonly canonicalRootFiles: readonly string[];
48
48
  readonly canonicalRootDirs: readonly string[];
49
49
  readonly canonicalSpecFiles: readonly string[];
50
+ readonly forbiddenHostAssetRootDirs: readonly string[];
50
51
  readonly generatedRuntimePatterns: readonly string[];
51
52
  readonly legacyMergeBeforeDeleteFiles: readonly string[];
52
53
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "4.3.3",
3
+ "version": "4.3.5",
4
4
  "description": "Planu — MCP Server for Spec Driven Development with native Rust acceleration for hot paths. Cross-platform (Linux/macOS/Windows, x64/arm64, glibc/musl).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,14 +32,14 @@
32
32
  "packageName": "@planu/core"
33
33
  },
34
34
  "optionalDependencies": {
35
- "@planu/core-darwin-arm64": "4.3.3",
36
- "@planu/core-darwin-x64": "4.3.3",
37
- "@planu/core-linux-arm64-gnu": "4.3.3",
38
- "@planu/core-linux-arm64-musl": "4.3.3",
39
- "@planu/core-linux-x64-gnu": "4.3.3",
40
- "@planu/core-linux-x64-musl": "4.3.3",
41
- "@planu/core-win32-arm64-msvc": "4.3.3",
42
- "@planu/core-win32-x64-msvc": "4.3.3"
35
+ "@planu/core-darwin-arm64": "4.3.5",
36
+ "@planu/core-darwin-x64": "4.3.5",
37
+ "@planu/core-linux-arm64-gnu": "4.3.5",
38
+ "@planu/core-linux-arm64-musl": "4.3.5",
39
+ "@planu/core-linux-x64-gnu": "4.3.5",
40
+ "@planu/core-linux-x64-musl": "4.3.5",
41
+ "@planu/core-win32-arm64-msvc": "4.3.5",
42
+ "@planu/core-win32-x64-msvc": "4.3.5"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=24.0.0"