delimit-cli 3.1.0 → 3.1.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.
@@ -145,7 +145,7 @@ def evaluate_trigger(action: str, context: Optional[Dict] = None, repo: str = ".
145
145
  return {
146
146
  "tool": "gov.evaluate",
147
147
  "status": "not_available",
148
- "error": "Governance evaluation engine not running. This tool requires the governancegate package.",
148
+ "error": "Project not initialized for governance. Say 'initialize governance for this project' or run the delimit_init tool with your project path.",
149
149
  "action": action,
150
150
  "repo": repo,
151
151
  }
@@ -156,7 +156,7 @@ def new_task(title: str, scope: str, risk_level: str = "medium", repo: str = "."
156
156
  return {
157
157
  "tool": "gov.new_task",
158
158
  "status": "not_available",
159
- "error": "Governance task engine not running. This tool requires the governancegate package.",
159
+ "error": "Project not initialized for governance. Say 'initialize governance for this project' or run the delimit_init tool with your project path.",
160
160
  }
161
161
 
162
162
 
@@ -165,7 +165,7 @@ def run_task(task_id: str, repo: str = ".") -> Dict[str, Any]:
165
165
  return {
166
166
  "tool": "gov.run",
167
167
  "status": "not_available",
168
- "error": "Governance task engine not running. This tool requires the governancegate package.",
168
+ "error": "Project not initialized for governance. Say 'initialize governance for this project' or run the delimit_init tool with your project path.",
169
169
  }
170
170
 
171
171
 
@@ -174,7 +174,7 @@ def verify(task_id: str, repo: str = ".") -> Dict[str, Any]:
174
174
  return {
175
175
  "tool": "gov.verify",
176
176
  "status": "not_available",
177
- "error": "Governance task engine not running. This tool requires the governancegate package.",
177
+ "error": "Project not initialized for governance. Say 'initialize governance for this project' or run the delimit_init tool with your project path.",
178
178
  }
179
179
 
180
180
 
@@ -183,7 +183,7 @@ def evidence_index(task_id: str, repo: str = ".") -> Dict[str, Any]:
183
183
  return {
184
184
  "tool": "gov.evidence_index",
185
185
  "status": "not_available",
186
- "error": "Governance evidence engine not running. This tool requires the governancegate package.",
186
+ "error": "Project not initialized for governance. Say 'initialize governance for this project' or run the delimit_init tool with your project path.",
187
187
  }
188
188
 
189
189
 
@@ -192,5 +192,5 @@ def require_owner_approval(context: str, repo: str = ".") -> Dict[str, Any]:
192
192
  return {
193
193
  "tool": "gov.require_owner_approval",
194
194
  "status": "not_available",
195
- "error": "Governance approval engine not running. This tool requires the governancegate package.",
195
+ "error": "Project not initialized for governance. Say 'initialize governance for this project' or run the delimit_init tool with your project path.",
196
196
  }
@@ -15,6 +15,12 @@ logger = logging.getLogger("delimit.ai.os_bridge")
15
15
 
16
16
  OS_PACKAGE = Path("/home/delimit/.delimit_suite/packages/delimit-os")
17
17
 
18
+ _NOT_INIT_MSG = (
19
+ "Project not initialized for governance. "
20
+ "Say 'initialize governance for this project' "
21
+ "or run the delimit_init tool with your project path."
22
+ )
23
+
18
24
 
19
25
  def _ensure_os_path():
20
26
  if str(OS_PACKAGE) not in sys.path:
@@ -47,7 +53,7 @@ def create_plan(operation: str, target: str, parameters: Optional[Dict] = None,
47
53
  PLANS[plan_id] = plan
48
54
  return plan
49
55
  except ImportError:
50
- return {"error": "delimit-os not available", "fallback": True}
56
+ return {"error": _NOT_INIT_MSG, "fallback": True}
51
57
 
52
58
 
53
59
  def get_status() -> Dict[str, Any]:
@@ -62,7 +68,7 @@ def get_status() -> Dict[str, Any]:
62
68
  "tokens": len(TOKENS),
63
69
  }
64
70
  except ImportError:
65
- return {"status": "unavailable", "error": "delimit-os not loaded"}
71
+ return {"status": "unavailable", "error": _NOT_INIT_MSG}
66
72
 
67
73
 
68
74
  def check_gates(plan_id: str) -> Dict[str, Any]:
@@ -79,4 +85,4 @@ def check_gates(plan_id: str) -> Dict[str, Any]:
79
85
  "status": plan.get("status"),
80
86
  }
81
87
  except ImportError:
82
- return {"error": "delimit-os not available"}
88
+ return {"error": _NOT_INIT_MSG}
@@ -21,9 +21,12 @@ All tools follow the Adapter Boundary Contract v1.0:
21
21
 
22
22
  import json
23
23
  import logging
24
+ import os
25
+ import shutil
24
26
  import subprocess
25
27
  import traceback
26
28
  from datetime import datetime, timezone
29
+ from pathlib import Path
27
30
  from typing import Any, Dict, List, Optional
28
31
 
29
32
  from fastmcp import FastMCP
@@ -176,6 +179,84 @@ def delimit_zero_spec(
176
179
  return _safe_call(run_zero_spec, project_dir=project_dir, python_bin=python_bin)
177
180
 
178
181
 
182
+
183
+
184
+ @mcp.tool()
185
+ def delimit_init(
186
+ project_path: str = ".",
187
+ preset: str = "default",
188
+ ) -> Dict[str, Any]:
189
+ """Initialize Delimit governance for a project. Creates .delimit/policies.yml and ledger directory.
190
+
191
+ Args:
192
+ project_path: Project root directory.
193
+ preset: Policy preset — strict, default, or relaxed.
194
+ """
195
+ VALID_PRESETS = ("strict", "default", "relaxed")
196
+ if preset not in VALID_PRESETS:
197
+ return {
198
+ "error": "invalid_preset",
199
+ "message": f"Preset must be one of {VALID_PRESETS}, got '{preset}'",
200
+ }
201
+
202
+ root = Path(project_path).resolve()
203
+ delimit_dir = root / ".delimit"
204
+ policies_file = delimit_dir / "policies.yml"
205
+ ledger_dir = delimit_dir / "ledger"
206
+ events_file = ledger_dir / "events.jsonl"
207
+
208
+ # Idempotency check
209
+ if policies_file.exists() and ledger_dir.exists() and events_file.exists():
210
+ return {
211
+ "tool": "init",
212
+ "status": "already_initialized",
213
+ "project_path": str(root),
214
+ "preset": preset,
215
+ "message": f"Project already initialized at {delimit_dir}. No files overwritten.",
216
+ }
217
+
218
+ created = []
219
+
220
+ # 1. Create .delimit/ directory
221
+ if not delimit_dir.exists():
222
+ delimit_dir.mkdir(parents=True, exist_ok=True)
223
+ created.append(str(delimit_dir))
224
+
225
+ # 2. Create policies.yml from preset
226
+ if not policies_file.exists():
227
+ preset_source = Path(__file__).resolve().parent.parent / "core" / "policies" / f"{preset}.yml"
228
+ if preset_source.exists():
229
+ shutil.copy2(str(preset_source), str(policies_file))
230
+ else:
231
+ # Fallback: write a minimal default
232
+ fallback_content = (
233
+ f"# Delimit Policy Preset: {preset}\n"
234
+ "# Generated by delimit_init\n"
235
+ "override_defaults: false\n"
236
+ "rules: []\n"
237
+ )
238
+ policies_file.write_text(fallback_content)
239
+ created.append(str(policies_file))
240
+
241
+ # 3. Create ledger directory
242
+ if not ledger_dir.exists():
243
+ ledger_dir.mkdir(parents=True, exist_ok=True)
244
+ created.append(str(ledger_dir))
245
+
246
+ # 4. Create empty events.jsonl
247
+ if not events_file.exists():
248
+ events_file.touch()
249
+ created.append(str(events_file))
250
+
251
+ return {
252
+ "tool": "init",
253
+ "status": "initialized",
254
+ "project_path": str(root),
255
+ "preset": preset,
256
+ "created": created,
257
+ "message": f"Governance initialized with '{preset}' preset. {len(created)} items created.",
258
+ }
259
+
179
260
  # ═══════════════════════════════════════════════════════════════════════
180
261
  # TIER 2: PLATFORM — OS, Governance, Memory, Vault
181
262
  # ═══════════════════════════════════════════════════════════════════════
@@ -252,7 +333,7 @@ def delimit_gov_policy(repo: str = ".") -> Dict[str, Any]:
252
333
 
253
334
  @mcp.tool()
254
335
  def delimit_gov_evaluate(action: str, context: Optional[Dict[str, Any]] = None, repo: str = ".") -> Dict[str, Any]:
255
- """Evaluate if governance is required for an action.
336
+ """Evaluate if governance is required for an action (requires governancegate).
256
337
 
257
338
  Args:
258
339
  action: The action to evaluate.
@@ -265,7 +346,7 @@ def delimit_gov_evaluate(action: str, context: Optional[Dict[str, Any]] = None,
265
346
 
266
347
  @mcp.tool()
267
348
  def delimit_gov_new_task(title: str, scope: str, risk_level: str = "medium", repo: str = ".") -> Dict[str, Any]:
268
- """Create a new governance task.
349
+ """Create a new governance task (requires governancegate).
269
350
 
270
351
  Args:
271
352
  title: Task title.
@@ -279,7 +360,7 @@ def delimit_gov_new_task(title: str, scope: str, risk_level: str = "medium", rep
279
360
 
280
361
  @mcp.tool()
281
362
  def delimit_gov_run(task_id: str, repo: str = ".") -> Dict[str, Any]:
282
- """Run a governance task.
363
+ """Run a governance task (requires governancegate).
283
364
 
284
365
  Args:
285
366
  task_id: Task ID to run.
@@ -291,7 +372,7 @@ def delimit_gov_run(task_id: str, repo: str = ".") -> Dict[str, Any]:
291
372
 
292
373
  @mcp.tool()
293
374
  def delimit_gov_verify(task_id: str, repo: str = ".") -> Dict[str, Any]:
294
- """Verify a governance task.
375
+ """Verify a governance task (requires governancegate).
295
376
 
296
377
  Args:
297
378
  task_id: Task ID to verify.
@@ -412,7 +493,7 @@ def delimit_deploy_publish(app: str, git_ref: Optional[str] = None) -> Dict[str,
412
493
 
413
494
  @mcp.tool()
414
495
  def delimit_deploy_verify(app: str, env: str, git_ref: Optional[str] = None) -> Dict[str, Any]:
415
- """Verify deployment health.
496
+ """Verify deployment health (experimental).
416
497
 
417
498
  Args:
418
499
  app: Application name.
@@ -452,7 +533,7 @@ def delimit_deploy_status(app: str, env: str) -> Dict[str, Any]:
452
533
 
453
534
  @mcp.tool()
454
535
  def delimit_intel_dataset_register(name: str, schema: Dict[str, Any], description: Optional[str] = None) -> Dict[str, Any]:
455
- """Register a new dataset with schema.
536
+ """Register a new dataset with schema (coming soon).
456
537
 
457
538
  Args:
458
539
  name: Dataset name.
@@ -465,14 +546,14 @@ def delimit_intel_dataset_register(name: str, schema: Dict[str, Any], descriptio
465
546
 
466
547
  @mcp.tool()
467
548
  def delimit_intel_dataset_list() -> Dict[str, Any]:
468
- """List registered datasets."""
549
+ """List registered datasets (coming soon)."""
469
550
  from backends.intel_bridge import dataset_list
470
551
  return _safe_call(dataset_list)
471
552
 
472
553
 
473
554
  @mcp.tool()
474
555
  def delimit_intel_dataset_freeze(dataset_id: str) -> Dict[str, Any]:
475
- """Mark dataset as immutable.
556
+ """Mark dataset as immutable (coming soon).
476
557
 
477
558
  Args:
478
559
  dataset_id: Dataset identifier.
@@ -483,7 +564,7 @@ def delimit_intel_dataset_freeze(dataset_id: str) -> Dict[str, Any]:
483
564
 
484
565
  @mcp.tool()
485
566
  def delimit_intel_snapshot_ingest(data: Dict[str, Any], provenance: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
486
- """Store research snapshot with provenance.
567
+ """Store research snapshot with provenance (coming soon).
487
568
 
488
569
  Args:
489
570
  data: Snapshot data.
@@ -495,7 +576,7 @@ def delimit_intel_snapshot_ingest(data: Dict[str, Any], provenance: Optional[Dic
495
576
 
496
577
  @mcp.tool()
497
578
  def delimit_intel_query(dataset_id: str, query: str, parameters: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
498
- """Execute deterministic query on dataset.
579
+ """Execute deterministic query on dataset (coming soon).
499
580
 
500
581
  Args:
501
582
  dataset_id: Dataset to query.
@@ -539,7 +620,7 @@ def delimit_generate_scaffold(project_type: str, name: str, packages: Optional[L
539
620
 
540
621
  @mcp.tool()
541
622
  def delimit_repo_diagnose(target: str = ".") -> Dict[str, Any]:
542
- """Diagnose repository health issues.
623
+ """Diagnose repository health issues (experimental).
543
624
 
544
625
  Args:
545
626
  target: Repository path.
@@ -550,7 +631,7 @@ def delimit_repo_diagnose(target: str = ".") -> Dict[str, Any]:
550
631
 
551
632
  @mcp.tool()
552
633
  def delimit_repo_analyze(target: str = ".") -> Dict[str, Any]:
553
- """Analyze repository structure and quality.
634
+ """Analyze repository structure and quality (experimental).
554
635
 
555
636
  Args:
556
637
  target: Repository path.
@@ -561,7 +642,7 @@ def delimit_repo_analyze(target: str = ".") -> Dict[str, Any]:
561
642
 
562
643
  @mcp.tool()
563
644
  def delimit_repo_config_validate(target: str = ".") -> Dict[str, Any]:
564
- """Validate configuration files.
645
+ """Validate configuration files (experimental).
565
646
 
566
647
  Args:
567
648
  target: Repository or config path.
@@ -572,7 +653,7 @@ def delimit_repo_config_validate(target: str = ".") -> Dict[str, Any]:
572
653
 
573
654
  @mcp.tool()
574
655
  def delimit_repo_config_audit(target: str = ".") -> Dict[str, Any]:
575
- """Audit configuration compliance.
656
+ """Audit configuration compliance (experimental).
576
657
 
577
658
  Args:
578
659
  target: Repository or config path.
@@ -596,7 +677,7 @@ def delimit_security_scan(target: str = ".") -> Dict[str, Any]:
596
677
 
597
678
  @mcp.tool()
598
679
  def delimit_security_audit(target: str = ".") -> Dict[str, Any]:
599
- """Audit security compliance.
680
+ """Audit security compliance (experimental).
600
681
 
601
682
  Args:
602
683
  target: Repository or file path.
@@ -639,7 +720,7 @@ def delimit_evidence_verify(bundle_id: Optional[str] = None, bundle_path: Option
639
720
 
640
721
  @mcp.tool()
641
722
  def delimit_release_plan(environment: str, version: str, repository: str, services: Optional[List[str]] = None) -> Dict[str, Any]:
642
- """Create deployment plan with approval gates.
723
+ """Create deployment plan with approval gates (experimental).
643
724
 
644
725
  Args:
645
726
  environment: Target environment (staging/production).
@@ -653,7 +734,7 @@ def delimit_release_plan(environment: str, version: str, repository: str, servic
653
734
 
654
735
  @mcp.tool()
655
736
  def delimit_release_validate(environment: str, version: str) -> Dict[str, Any]:
656
- """Validate release readiness.
737
+ """Validate release readiness (experimental).
657
738
 
658
739
  Args:
659
740
  environment: Target environment.
@@ -665,7 +746,7 @@ def delimit_release_validate(environment: str, version: str) -> Dict[str, Any]:
665
746
 
666
747
  @mcp.tool()
667
748
  def delimit_release_status(environment: str) -> Dict[str, Any]:
668
- """Check deployment status.
749
+ """Check deployment status (experimental).
669
750
 
670
751
  Args:
671
752
  environment: Target environment.
@@ -676,7 +757,7 @@ def delimit_release_status(environment: str) -> Dict[str, Any]:
676
757
 
677
758
  @mcp.tool()
678
759
  def delimit_release_rollback(environment: str, version: str, to_version: str) -> Dict[str, Any]:
679
- """Rollback deployment to previous version.
760
+ """Rollback deployment to previous version (experimental).
680
761
 
681
762
  Args:
682
763
  environment: Target environment.
@@ -689,7 +770,7 @@ def delimit_release_rollback(environment: str, version: str, to_version: str) ->
689
770
 
690
771
  @mcp.tool()
691
772
  def delimit_release_history(environment: str, limit: int = 10) -> Dict[str, Any]:
692
- """Show release history.
773
+ """Show release history (experimental).
693
774
 
694
775
  Args:
695
776
  environment: Target environment.
@@ -703,7 +784,7 @@ def delimit_release_history(environment: str, limit: int = 10) -> Dict[str, Any]
703
784
 
704
785
  @mcp.tool()
705
786
  def delimit_cost_analyze(target: str = ".") -> Dict[str, Any]:
706
- """Analyze cost and spending patterns.
787
+ """Analyze cost and spending patterns (experimental).
707
788
 
708
789
  Args:
709
790
  target: Project or infrastructure path.
@@ -714,7 +795,7 @@ def delimit_cost_analyze(target: str = ".") -> Dict[str, Any]:
714
795
 
715
796
  @mcp.tool()
716
797
  def delimit_cost_optimize(target: str = ".") -> Dict[str, Any]:
717
- """Generate cost optimization recommendations.
798
+ """Generate cost optimization recommendations (experimental).
718
799
 
719
800
  Args:
720
801
  target: Project or infrastructure path.
@@ -725,7 +806,7 @@ def delimit_cost_optimize(target: str = ".") -> Dict[str, Any]:
725
806
 
726
807
  @mcp.tool()
727
808
  def delimit_cost_alert(action: str = "list") -> Dict[str, Any]:
728
- """Manage cost alerts and notifications.
809
+ """Manage cost alerts and notifications (experimental).
729
810
 
730
811
  Args:
731
812
  action: Action (list/create/delete/update).
@@ -738,7 +819,7 @@ def delimit_cost_alert(action: str = "list") -> Dict[str, Any]:
738
819
 
739
820
  @mcp.tool()
740
821
  def delimit_data_validate(target: str = ".") -> Dict[str, Any]:
741
- """Validate data integrity.
822
+ """Validate data integrity (experimental).
742
823
 
743
824
  Args:
744
825
  target: Data source or path.
@@ -749,7 +830,7 @@ def delimit_data_validate(target: str = ".") -> Dict[str, Any]:
749
830
 
750
831
  @mcp.tool()
751
832
  def delimit_data_migrate(target: str = ".") -> Dict[str, Any]:
752
- """Execute data migration (plan-only by default).
833
+ """Execute data migration (experimental, plan-only by default).
753
834
 
754
835
  Args:
755
836
  target: Data source or migration path.
@@ -760,7 +841,7 @@ def delimit_data_migrate(target: str = ".") -> Dict[str, Any]:
760
841
 
761
842
  @mcp.tool()
762
843
  def delimit_data_backup(target: str = ".") -> Dict[str, Any]:
763
- """Create data backups.
844
+ """Create data backups (experimental).
764
845
 
765
846
  Args:
766
847
  target: Data source to back up.
@@ -773,7 +854,7 @@ def delimit_data_backup(target: str = ".") -> Dict[str, Any]:
773
854
 
774
855
  @mcp.tool()
775
856
  def delimit_obs_metrics(query: str, time_range: str = "1h", source: Optional[str] = None) -> Dict[str, Any]:
776
- """Query and analyze metrics.
857
+ """Query and analyze metrics (experimental).
777
858
 
778
859
  Args:
779
860
  query: Metrics query.
@@ -786,7 +867,7 @@ def delimit_obs_metrics(query: str, time_range: str = "1h", source: Optional[str
786
867
 
787
868
  @mcp.tool()
788
869
  def delimit_obs_logs(query: str, time_range: str = "1h", source: Optional[str] = None) -> Dict[str, Any]:
789
- """Query and search logs.
870
+ """Query and search logs (experimental).
790
871
 
791
872
  Args:
792
873
  query: Log search query.
@@ -799,7 +880,7 @@ def delimit_obs_logs(query: str, time_range: str = "1h", source: Optional[str] =
799
880
 
800
881
  @mcp.tool()
801
882
  def delimit_obs_alerts(action: str, alert_rule: Optional[Dict[str, Any]] = None, rule_id: Optional[str] = None) -> Dict[str, Any]:
802
- """Manage alerting rules.
883
+ """Manage alerting rules (experimental).
803
884
 
804
885
  Args:
805
886
  action: Action (list/create/delete/update).
@@ -812,7 +893,7 @@ def delimit_obs_alerts(action: str, alert_rule: Optional[Dict[str, Any]] = None,
812
893
 
813
894
  @mcp.tool()
814
895
  def delimit_obs_status() -> Dict[str, Any]:
815
- """Get observability system status."""
896
+ """Get observability system status (experimental)."""
816
897
  from backends.ops_bridge import obs_status
817
898
  return _safe_call(obs_status)
818
899
 
@@ -821,7 +902,7 @@ def delimit_obs_status() -> Dict[str, Any]:
821
902
 
822
903
  @mcp.tool()
823
904
  def delimit_design_extract_tokens(figma_file_key: str, token_types: Optional[List[str]] = None) -> Dict[str, Any]:
824
- """Extract design tokens from Figma.
905
+ """Extract design tokens from Figma (coming soon).
825
906
 
826
907
  Args:
827
908
  figma_file_key: Figma file key.
@@ -833,7 +914,7 @@ def delimit_design_extract_tokens(figma_file_key: str, token_types: Optional[Lis
833
914
 
834
915
  @mcp.tool()
835
916
  def delimit_design_generate_component(component_name: str, figma_node_id: Optional[str] = None, output_path: Optional[str] = None) -> Dict[str, Any]:
836
- """Generate Next.js component from Figma design.
917
+ """Generate Next.js component from Figma design (coming soon).
837
918
 
838
919
  Args:
839
920
  component_name: Component name.
@@ -846,7 +927,7 @@ def delimit_design_generate_component(component_name: str, figma_node_id: Option
846
927
 
847
928
  @mcp.tool()
848
929
  def delimit_design_generate_tailwind(figma_file_key: str, output_path: Optional[str] = None) -> Dict[str, Any]:
849
- """Generate Tailwind config from Figma design tokens.
930
+ """Generate Tailwind config from Figma design tokens (coming soon).
850
931
 
851
932
  Args:
852
933
  figma_file_key: Figma file key.
@@ -858,7 +939,7 @@ def delimit_design_generate_tailwind(figma_file_key: str, output_path: Optional[
858
939
 
859
940
  @mcp.tool()
860
941
  def delimit_design_validate_responsive(project_path: str, check_types: Optional[List[str]] = None) -> Dict[str, Any]:
861
- """Validate responsive design patterns.
942
+ """Validate responsive design patterns (coming soon).
862
943
 
863
944
  Args:
864
945
  project_path: Project path to validate.
@@ -870,7 +951,7 @@ def delimit_design_validate_responsive(project_path: str, check_types: Optional[
870
951
 
871
952
  @mcp.tool()
872
953
  def delimit_design_component_library(project_path: str, output_format: str = "json") -> Dict[str, Any]:
873
- """Generate component library documentation.
954
+ """Generate component library documentation (coming soon).
874
955
 
875
956
  Args:
876
957
  project_path: Project path.
@@ -884,7 +965,7 @@ def delimit_design_component_library(project_path: str, output_format: str = "js
884
965
 
885
966
  @mcp.tool()
886
967
  def delimit_story_generate(component_path: str, story_name: Optional[str] = None, variants: Optional[List[str]] = None) -> Dict[str, Any]:
887
- """Generate Storybook story for a component.
968
+ """Generate Storybook story for a component (coming soon).
888
969
 
889
970
  Args:
890
971
  component_path: Path to the component file.
@@ -897,7 +978,7 @@ def delimit_story_generate(component_path: str, story_name: Optional[str] = None
897
978
 
898
979
  @mcp.tool()
899
980
  def delimit_story_visual_test(url: str, project_path: Optional[str] = None, threshold: float = 0.05) -> Dict[str, Any]:
900
- """Run visual regression test with Playwright screenshots.
981
+ """Run visual regression test with Playwright screenshots (coming soon).
901
982
 
902
983
  Args:
903
984
  url: URL to test.
@@ -910,7 +991,7 @@ def delimit_story_visual_test(url: str, project_path: Optional[str] = None, thre
910
991
 
911
992
  @mcp.tool()
912
993
  def delimit_story_build(project_path: str, output_dir: Optional[str] = None) -> Dict[str, Any]:
913
- """Build Storybook static site.
994
+ """Build Storybook static site (coming soon).
914
995
 
915
996
  Args:
916
997
  project_path: Project path.
@@ -922,7 +1003,7 @@ def delimit_story_build(project_path: str, output_dir: Optional[str] = None) ->
922
1003
 
923
1004
  @mcp.tool()
924
1005
  def delimit_story_accessibility(project_path: str, standards: str = "WCAG2AA") -> Dict[str, Any]:
925
- """Run WCAG accessibility tests on components.
1006
+ """Run WCAG accessibility tests on components (coming soon).
926
1007
 
927
1008
  Args:
928
1009
  project_path: Project path.
@@ -936,7 +1017,7 @@ def delimit_story_accessibility(project_path: str, standards: str = "WCAG2AA") -
936
1017
 
937
1018
  @mcp.tool()
938
1019
  def delimit_test_generate(project_path: str, source_files: Optional[List[str]] = None, framework: str = "jest") -> Dict[str, Any]:
939
- """Generate tests for source code.
1020
+ """Generate tests for source code (experimental).
940
1021
 
941
1022
  Args:
942
1023
  project_path: Project path.
@@ -949,7 +1030,7 @@ def delimit_test_generate(project_path: str, source_files: Optional[List[str]] =
949
1030
 
950
1031
  @mcp.tool()
951
1032
  def delimit_test_coverage(project_path: str, threshold: int = 80) -> Dict[str, Any]:
952
- """Analyze test coverage.
1033
+ """Analyze test coverage (experimental).
953
1034
 
954
1035
  Args:
955
1036
  project_path: Project path.
@@ -961,7 +1042,7 @@ def delimit_test_coverage(project_path: str, threshold: int = 80) -> Dict[str, A
961
1042
 
962
1043
  @mcp.tool()
963
1044
  def delimit_test_smoke(project_path: str, test_suite: Optional[str] = None) -> Dict[str, Any]:
964
- """Run smoke tests.
1045
+ """Run smoke tests (experimental).
965
1046
 
966
1047
  Args:
967
1048
  project_path: Project path.
@@ -975,7 +1056,7 @@ def delimit_test_smoke(project_path: str, test_suite: Optional[str] = None) -> D
975
1056
 
976
1057
  @mcp.tool()
977
1058
  def delimit_docs_generate(target: str = ".") -> Dict[str, Any]:
978
- """Generate documentation for a project.
1059
+ """Generate documentation for a project (experimental).
979
1060
 
980
1061
  Args:
981
1062
  target: Project path.
@@ -986,7 +1067,7 @@ def delimit_docs_generate(target: str = ".") -> Dict[str, Any]:
986
1067
 
987
1068
  @mcp.tool()
988
1069
  def delimit_docs_validate(target: str = ".") -> Dict[str, Any]:
989
- """Validate documentation quality and completeness.
1070
+ """Validate documentation quality and completeness (experimental).
990
1071
 
991
1072
  Args:
992
1073
  target: Project path.
@@ -1128,7 +1209,7 @@ async def delimit_sensor_github_issue(
1128
1209
  def delimit_version() -> Dict[str, Any]:
1129
1210
  """Return Delimit unified server version, all tiers, and tool count."""
1130
1211
  tiers = {
1131
- "tier1_core": ["lint", "diff", "policy", "ledger", "impact", "semver", "explain", "zero_spec"],
1212
+ "tier1_core": ["lint", "diff", "policy", "ledger", "impact", "semver", "explain", "zero_spec", "init"],
1132
1213
  "tier2_platform": [
1133
1214
  "os.plan", "os.status", "os.gates",
1134
1215
  "gov.health", "gov.status", "gov.policy", "gov.evaluate", "gov.new_task", "gov.run", "gov.verify",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "delimit-cli",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "AI agent guardrails for developers. Install governance tools into Claude Code with one command.",
5
5
  "main": "index.js",
6
6
  "bin": {