New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

knowzcode

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

knowzcode - npm Package Compare versions

Comparing version
0.7.0
to
0.7.2
+22
.claude-plugin/marketplace.json
{
"name": "knowzcode-marketplace",
"owner": {
"name": "Alex Headscarf",
"email": "alexheadscarf@gmail.com"
},
"metadata": {
"description": "Official KnowzCode plugin marketplace - Platform-agnostic AI development methodology",
"version": "0.7.2"
},
"plugins": [
{
"name": "kc",
"source": "./",
"description": "KnowzCode - Platform-agnostic AI development methodology with TDD, quality gates, and structured workflows",
"version": "0.7.2",
"author": {
"name": "Alex Headscarf"
}
}
]
}
+1
-1
{
"name": "kc",
"description": "KnowzCode - Platform-agnostic AI development methodology with TDD, quality gates, and structured workflows",
"version": "0.7.0",
"version": "0.7.2",
"keywords": ["tdd", "development-methodology", "quality-gates", "agents", "code-review"],

@@ -6,0 +6,0 @@ "author": {

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ # Claude Code Execution Model

{
"name": "knowzcode",
"version": "0.7.0",
"version": "0.7.2",
"description": "Platform-agnostic AI development methodology with TDD, quality gates, and structured workflows",

@@ -5,0 +5,0 @@ "type": "module",

@@ -9,3 +9,3 @@ # KnowzCode

[![Claude Code Plugin](https://img.shields.io/badge/Claude_Code-Plugin-purple)](https://github.com/knowz-io/knowzcode)
[![Version](https://img.shields.io/badge/version-0.7.0-blue)](https://github.com/knowz-io/knowzcode/releases)
[![Version](https://img.shields.io/badge/version-0.7.2-blue)](https://github.com/knowz-io/knowzcode/releases)

@@ -12,0 +12,0 @@ [Installation](#installation) · [Quick Start](#quick-start) · [When to Use It](#when-to-use-knowzcode) · [How It Works](#how-it-works) · [Commands](#commands) · [Docs](#documentation)

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ # Agent-to-Vault Integration

@@ -0,0 +0,0 @@ # Vault Configuration Details

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ # KnowzCode Init — Template Files

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ # Error Handling Reference

@@ -0,0 +0,0 @@ # Vault Discovery and Multi-Vault Selection

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ ---

@@ -0,0 +0,0 @@ # Parallel Teams Orchestration — Work Skill (Tier 3)

@@ -0,0 +0,0 @@ # Quality Gates — Work Skill

@@ -0,0 +0,0 @@ # Agent Spawn Prompts — Work Skill

@@ -0,0 +0,0 @@ ---

{
"name": "alias-resolver",
"version": "0.7.0",
"description": "Resolves friendly natural-language aliases to KnowzCode canonical values (phase, audit, plan, workgroup_type).",
"parameters": [
{"name": "domain", "type": "string", "required": true},
{"name": "text", "type": "string", "required": false}
],
"actions": [
{
"type": "python",
"code": "domain = (inputs.get('domain') or '').strip().lower()\ntext = (inputs.get('text') or '').strip().lower()\nresult = {'value': None}\nphase_map = {\n '1a': {'agent': 'analyst', 'prompt': 'knowzcode/prompts/[LOOP_1A]__Propose_Change_Set.md'},\n '1b': {'agent': 'architect', 'prompt': 'knowzcode/prompts/[LOOP_1B]__Draft_Specs.md'},\n '2a': {'agent': 'builder', 'prompt': 'knowzcode/prompts/[LOOP_2A]__Implement_Change_Set.md'},\n '2b': {'agent': 'reviewer', 'prompt': 'knowzcode/prompts/[LOOP_2B]__Verify_Implementation.md'},\n '3': {'agent': 'closer', 'prompt': 'knowzcode/prompts/[LOOP_3]__Finalize_And_Commit.md'}\n}\nphase_synonyms = {\n '1a': ['1a','loop 1a','analyze','analysis','impact','scope','change set','proposal'],\n '1b': ['1b','loop 1b','spec','specs','draft','design','blueprint'],\n '2a': ['2a','loop 2a','implement','implementation','build','code','develop'],\n '2b': ['2b','loop 2b','verify','verification','audit','test','qa','review'],\n '3': ['3','loop 3','final','finalize','finalization','commit','wrap up','close']\n}\naudit_map = {\n 'spec': 'knowzcode/prompts/Spec_Verification_Checkpoint.md',\n 'implementation': 'knowzcode/prompts/[LOOP_2B]__Verify_Implementation.md',\n 'architecture': None,\n 'security': None,\n 'integration': None\n}\naudit_synonyms = {\n 'spec': ['spec','specs','specification','checkpoint'],\n 'implementation': ['implementation','code','verify implementation','loop 2b'],\n 'architecture': ['architecture','arch','diagram','flowchart','structure'],\n 'security': ['security','sec','owasp','vulnerability'],\n 'integration': ['integration','holistic','system','end to end','e2e']\n}\nworkgroup_map = {'feat': 'feat','feature': 'feat','fix': 'fix','bug': 'fix','bugfix': 'fix','refactor': 'refactor','cleanup': 'refactor','issue': 'issue','incident': 'issue'}\nif domain == 'phase':\n if not text:\n key = '1a'\n else:\n key = None\n for canonical, synonyms in phase_synonyms.items():\n if text == canonical or text in synonyms or any(s in text for s in synonyms):\n key = canonical\n break\n if key is None:\n for canonical in phase_map.keys():\n if text.replace(' ','') == canonical:\n key = canonical\n break\n if key is None:\n key = '1a'\n data = phase_map[key]\n result['value'] = key.upper()\n result['prompt'] = data['prompt']\n result['agent'] = data['agent']\n result['requires_workgroup'] = data['agent'] != 'analyst'\nelif domain == 'audit':\n if not text:\n key = 'spec'\n else:\n key = None\n for canonical, synonyms in audit_synonyms.items():\n if text == canonical or text in synonyms or any(s in text for s in synonyms):\n key = canonical\n break\n if key is None:\n key = 'spec'\n result['value'] = key\n result['prompt'] = audit_map.get(key)\n result['agent'] = 'reviewer'\nelif domain == 'plan':\n result['value'] = text or ''\n result['prompt'] = None\nelif domain == 'workgroup_type':\n if not text:\n value = 'feat'\n else:\n value = None\n for key, mapped in workgroup_map.items():\n if text == key or key in text:\n value = mapped\n break\n if value is None:\n value = workgroup_map.get(text, 'feat')\n result['value'] = value\nelse:\n result['value'] = text or ''\noutputs.update(result)\n"
}
]
}
{
"name": "architecture-diff",
"version": "0.7.0",
"description": "Highlights differences between specs and the Mermaid flowchart in knowzcode_architecture.md.",
"parameters": [],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\nimport re\narch = Path('knowzcode/knowzcode_architecture.md').read_text()\nspec_paths = list(Path('knowzcode/specs').glob('*.md'))\nnode_ids = {p.stem for p in spec_paths}\nmermaid_nodes = set(re.findall(r'([A-Z]{2,}_[A-Za-z0-9]+)', arch))\nmissing_in_arch = sorted(node_ids - mermaid_nodes)\nmissing_in_specs = sorted(mermaid_nodes - node_ids)\noutputs['missing_in_architecture'] = missing_in_arch\noutputs['missing_specs'] = missing_in_specs\n"
}
]
}
{
"name": "check-installation-status",
"version": "0.7.0",
"description": "Checks if KnowzCode is initialized in the current project and reports current status",
"parameters": [],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\n\nknowzcode_dir = Path('knowzcode')\n\nif not knowzcode_dir.exists():\n outputs['initialized'] = False\n outputs['commands_count'] = 0\n outputs['skills_count'] = 0\n outputs['agents_count'] = 0\n outputs['has_required_files'] = False\n exit()\n\n# Check required files exist\nrequired_files = [\n 'knowzcode_loop.md',\n 'knowzcode_tracker.md',\n 'knowzcode_project.md',\n 'knowzcode_architecture.md'\n]\n\nmissing_files = [f for f in required_files if not (knowzcode_dir / f).exists()]\nhas_required_files = len(missing_files) == 0\n\n# Count components from various possible locations\n\n# Check .claude directory\nclaude_dir = Path('.claude')\ncommands_count = 0\nskills_count = 0\nagents_count = 0\n\nif claude_dir.exists():\n if (claude_dir / 'commands').exists():\n commands_count = len(list((claude_dir / 'commands').glob('*.md')))\n if (claude_dir / 'skills').exists():\n skills_count = len(list((claude_dir / 'skills').glob('*.json')))\n if (claude_dir / 'agents').exists():\n agents_count = len(list((claude_dir / 'agents').glob('*.md')))\n if (claude_dir / 'subagents').exists():\n agents_count += len(list((claude_dir / 'subagents').glob('*.yaml')))\n\n# Also check top-level directories (plugin installation)\nif Path('commands').exists():\n commands_count = max(commands_count, len(list(Path('commands').glob('*.md'))))\nif Path('skills').exists():\n skills_count = max(skills_count, len(list(Path('skills').glob('*.json'))))\nif Path('agents').exists():\n agents_count = max(agents_count, len(list(Path('agents').glob('*.md'))))\n\noutputs['initialized'] = has_required_files\noutputs['commands_count'] = commands_count\noutputs['skills_count'] = skills_count\noutputs['agents_count'] = agents_count\noutputs['has_required_files'] = has_required_files\noutputs['missing_files'] = missing_files if missing_files else None"
}
]
}
{
"name": "environment-guard",
"version": "0.7.0",
"description": "Verifies that knowzcode/environment_context.md no longer contains placeholder brackets.",
"parameters": [],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\ntext = Path('knowzcode/environment_context.md').read_text()\nplaceholders = [line.strip() for line in text.splitlines() if '[' in line and ']' in line]\nif placeholders:\n raise ValueError('environment_context.md still contains placeholders: ' + ', '.join(placeholders[:5]))\n"
}
]
}
{
"name": "generate-workgroup-id",
"version": "0.7.0",
"description": "Generates a WorkGroupID following the KnowzCode convention [type]-[slug]-YYYYMMDD-HHMMSS. The slug is a 2-4 word descriptor extracted from the goal.",
"parameters": [
{
"name": "type",
"type": "string",
"required": true,
"description": "One of feat, fix, refactor, issue"
},
{
"name": "slug",
"type": "string",
"required": false,
"description": "A 2-4 word kebab-case descriptor (e.g., 'auth-jwt', 'dark-mode'). If not provided, generates ID without slug."
}
],
"actions": [
{
"type": "python",
"code": "import datetime\nimport re\nallowed = {'feat', 'fix', 'refactor', 'issue'}\nwg_type = inputs['type']\nif wg_type not in allowed:\n raise ValueError(f'Invalid type {wg_type!r}, expected one of {sorted(allowed)}')\ntimestamp = datetime.datetime.utcnow().strftime('%Y%m%d-%H%M%S')\nslug = inputs.get('slug', '')\nif slug:\n # Sanitize slug: lowercase, replace spaces with hyphens, remove non-alphanumeric\n slug = re.sub(r'[^a-z0-9-]', '', slug.lower().replace(' ', '-'))\n slug = re.sub(r'-+', '-', slug).strip('-')[:25] # Max 25 chars\n outputs['workgroup_id'] = f'{wg_type}-{slug}-{timestamp}'\nelse:\n outputs['workgroup_id'] = f'{wg_type}-{timestamp}'"
}
]
}
{
"name": "install-knowzcode",
"version": "0.7.0",
"description": "Initializes KnowzCode directory structure and required files in the current project",
"parameters": [
{
"name": "force",
"type": "boolean",
"required": false,
"description": "Force reinstall even if knowzcode/ exists"
}
],
"actions": [
{
"type": "python",
"code": "import os\nimport json\nfrom pathlib import Path\nfrom datetime import datetime\n\n# Configuration\ntarget_dir = Path('knowzcode')\nforce = inputs.get('force', False)\n\n# Check if target exists\nif target_dir.exists() and not force:\n outputs['success'] = False\n outputs['error'] = 'knowzcode/ already exists. Use force=true to reinitialize'\n outputs['already_installed'] = True\n exit()\n\n# Create directory structure\ntarget_dir.mkdir(exist_ok=True)\n(target_dir / 'specs').mkdir(exist_ok=True)\n(target_dir / 'workgroups').mkdir(exist_ok=True)\n(target_dir / 'prompts').mkdir(exist_ok=True)\n(target_dir / 'planning').mkdir(exist_ok=True)\n\n# Create .gitignore if it doesn't exist\ngitignore_path = target_dir / '.gitignore'\nif not gitignore_path.exists():\n gitignore_content = '''# KnowzCode gitignore - protects environment-specific files\n\n# Environment-specific (contains local paths, commands)\nenvironment_context.md\n\n# Session-specific work (can be regenerated)\nworkgroups/\n\n# Personal notes and scratch files\n*.local.md\n.scratch/\n'''\n with open(gitignore_path, 'w') as f:\n f.write(gitignore_content)\n\n# Note: The actual template files (knowzcode_loop.md, etc.) should be copied\n# from the plugin template directory or created by the /kc:init command.\n# This skill creates the structure; the command copies the content.\n\noutputs['success'] = True\noutputs['target_dir'] = str(target_dir)\noutputs['directories_created'] = ['specs', 'workgroups', 'prompts', 'planning']\noutputs['gitignore_created'] = not gitignore_path.exists()\noutputs['message'] = f'KnowzCode directory structure created at {target_dir}/'"
}
]
}
{
"name": "load-core-context",
"version": "0.7.0",
"description": "Loads the KnowzCode project overview, architecture, tracker, log header, and automation manifest for downstream steps.",
"parameters": [],
"actions": [
{
"type": "read_file",
"paths": [
"knowzcode/knowzcode_project.md",
"knowzcode/knowzcode_architecture.md",
"knowzcode/knowzcode_tracker.md",
"knowzcode/knowzcode_log.md",
"knowzcode/automation_manifest.md"
]
}
]
}
{
"name": "log-entry-builder",
"version": "0.7.0",
"description": "Appends structured entries to knowzcode/knowzcode_log.md with KnowzCode formatting.",
"parameters": [
{"name": "entry_type", "type": "string", "required": true},
{"name": "content", "type": "string", "required": true}
],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\nentry_type = inputs['entry_type']\ncontent = inputs['content'].strip()\npath = Path('knowzcode/knowzcode_log.md')\ntext = path.read_text()\nmarker = '---\n**[NEWEST ENTRIES APPEAR HERE - DO NOT REMOVE THIS MARKER]**'\nidx = text.index(marker) + len(marker)\nnew_entry = f"\n---\n**Type:** {entry_type}\n{content}\n"\nupdated = text[:idx] + new_entry + text[idx:]\npath.write_text(updated)"
}
]
}
{
"name": "spec-quality-check",
"version": "0.7.0",
"description": "Validates KnowzCode spec files for mandatory sections. Supports new 4-section format and legacy numbered format.",
"parameters": [
{"name": "node_id", "type": "string", "required": true}
],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\nimport re\nnode_id = inputs['node_id']\npath = Path('knowzcode/specs') / f'{node_id}.md'\nif not path.exists():\n raise FileNotFoundError(f'Spec for {node_id} not found')\ntext = path.read_text()\n\n# Check new format first\nnew_sections = ['## Rules & Decisions', '## Interfaces', '## Verification Criteria', '## Debt & Gaps']\nlegacy_sections = ['## 1. Purpose', '## 2. Dependencies & Triggers', '## 3. Interfaces', '## 4. Core Logic & Processing Steps', '## 5. Data Structures', '## 6. ARC Verification Criteria', '## 7. Technical Debt']\n\nnew_missing = [s for s in new_sections if s not in text]\nlegacy_missing = [s for s in legacy_sections if s not in text]\n\n# Use whichever format has fewer missing sections\nif len(new_missing) <= len(legacy_missing):\n outputs['format'] = 'v2'\n outputs['missing_sections'] = new_missing\nelse:\n outputs['format'] = 'legacy'\n outputs['missing_sections'] = legacy_missing\n outputs['deprecation_warning'] = 'Spec uses old numbered format. New specs should use: Rules & Decisions, Interfaces, Verification Criteria, Debt & Gaps'\n"
}
]
}
{
"name": "spec-template",
"version": "0.7.0",
"description": "Seeds or repairs KnowzCode spec files with the lean 4-section template.",
"parameters": [
{"name": "node_id", "type": "string", "required": true},
{"name": "label", "type": "string", "required": true}
],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\nfrom datetime import datetime\nnode_id = inputs['node_id']\nlabel = inputs['label']\npath = Path('knowzcode/specs') / f'{node_id}.md'\nnow = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%SZ')\ntemplate_lines = [\n f'# {node_id}: {label}',\n '',\n f'**Updated:** {now}',\n '**Status:** Draft',\n '',\n '## Rules & Decisions',\n '- [Key architectural decisions, business rules, constraints, and purpose]',\n '',\n '## Interfaces',\n '- [Public contracts: inputs, outputs, API signatures, dependencies, events]',\n '',\n '## Verification Criteria',\n '- VERIFY: [testable assertion 1]',\n '- VERIFY: [testable assertion 2]',\n '',\n '## Debt & Gaps',\n '- [Known limitations and future work, or \"None\"]',\n ''\n]\ntemplate = '\\n'.join(template_lines)\nif not path.exists():\n path.write_text(template + '\\n')\n outputs['created'] = True\nelse:\n text = path.read_text()\n new_sections = ['## Rules & Decisions', '## Interfaces', '## Verification Criteria', '## Debt & Gaps']\n if all(section in text for section in new_sections):\n outputs['created'] = False\n else:\n merged = text.strip() + '\\n\\n<!-- Template sections restored -->\\n' + template + '\\n'\n path.write_text(merged)\n outputs['created'] = False"
}
]
}
{
"name": "spec-validator",
"version": "0.7.0",
"description": "Validates NodeID specification completeness and quality. Supports new 4-section format (preferred) and legacy numbered sections (deprecated).",
"parameters": [
{
"name": "spec_path",
"type": "string",
"required": true,
"description": "Absolute path to the spec file to validate"
},
{
"name": "node_id",
"type": "string",
"required": true,
"description": "NodeID being validated (for error reporting)"
}
],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\nimport re\n\nspec_path = Path(inputs['spec_path'])\nnode_id = inputs['node_id']\n\nif not spec_path.exists():\n outputs['valid'] = False\n outputs['errors'] = [f'Spec file does not exist: {spec_path}']\n outputs['warnings'] = []\n outputs['score'] = 0\n outputs['node_id'] = node_id\n outputs['format'] = 'missing'\n exit()\n\ncontent = spec_path.read_text()\n\nerrors = []\nwarnings = []\nscore = 100\n\n# Detect format: new 4-section or legacy numbered\nnew_sections = {\n 'rules': r'##\\s*Rules\\s*(&|and)\\s*Decisions',\n 'interfaces': r'##\\s*Interfaces',\n 'verification': r'##\\s*Verification\\s*Criteria',\n 'debt': r'##\\s*Debt\\s*(&|and)\\s*Gaps'\n}\nlegacy_sections = {\n 'purpose': r'##\\s*1\\.\\s*Purpose',\n 'deps': r'##\\s*2\\.\\s*Dependencies',\n 'interfaces': r'##\\s*3\\.\\s*Interfaces',\n 'logic': r'##\\s*4\\.\\s*Core\\s*Logic',\n 'arc': r'##\\s*(6\\.\\s*Error\\s*Handling|7\\.\\s*ARC\\s*Verification)'\n}\n\nnew_count = sum(1 for p in new_sections.values() if re.search(p, content, re.IGNORECASE))\nlegacy_count = sum(1 for p in legacy_sections.values() if re.search(p, content, re.IGNORECASE))\n\nif new_count >= legacy_count:\n spec_format = 'v2'\n # Validate new 4-section format\n required = [\n (new_sections['rules'], 'Missing \"Rules & Decisions\" section'),\n (new_sections['interfaces'], 'Missing \"Interfaces\" section'),\n (new_sections['verification'], 'Missing \"Verification Criteria\" section'),\n (new_sections['debt'], 'Missing \"Debt & Gaps\" section')\n ]\n for pattern, error_msg in required:\n if not re.search(pattern, content, re.IGNORECASE):\n errors.append(error_msg)\n score -= 15\n \n # Check VERIFY: statements (minimum 2)\n verify_section = re.search(r'##\\s*Verification\\s*Criteria(.+?)(?=##|$)', content, re.DOTALL | re.IGNORECASE)\n if verify_section:\n verify_content = verify_section.group(1)\n verify_count = len(re.findall(r'VERIFY:', verify_content))\n if verify_count < 2:\n errors.append(f'Only {verify_count} VERIFY: statements found (minimum 2 required)')\n score -= 15\n else:\n errors.append('Verification Criteria section is empty or malformed')\n score -= 20\n \n # Check Rules has content\n rules_section = re.search(r'##\\s*Rules\\s*(&|and)\\s*Decisions(.+?)(?=##|$)', content, re.DOTALL | re.IGNORECASE)\n if rules_section:\n rules_content = rules_section.group(2).strip()\n if len(rules_content) < 20 or re.search(r'^\\s*-\\s*\\[', rules_content):\n warnings.append('Rules & Decisions section appears to have only placeholder content')\n score -= 10\n \n # Check Interfaces has content\n iface_section = re.search(r'##\\s*Interfaces(.+?)(?=##|$)', content, re.DOTALL | re.IGNORECASE)\n if iface_section:\n iface_content = iface_section.group(1).strip()\n if len(iface_content) < 20 or re.search(r'^\\s*-\\s*\\[', iface_content):\n warnings.append('Interfaces section appears to have only placeholder content')\n score -= 10\nelse:\n spec_format = 'legacy'\n warnings.append('DEPRECATED: Spec uses old numbered format. Will be migrated when next touched during finalization.')\n \n # Validate legacy format\n required = [\n (legacy_sections['purpose'], 'Missing \"1. Purpose\" section'),\n (legacy_sections['deps'], 'Missing \"2. Dependencies\" section'),\n (legacy_sections['interfaces'], 'Missing \"3. Interfaces\" section'),\n (legacy_sections['logic'], 'Missing \"4. Core Logic\" section'),\n (legacy_sections['arc'], 'Missing ARC/Error Handling section')\n ]\n for pattern, error_msg in required:\n if not re.search(pattern, content, re.IGNORECASE):\n errors.append(error_msg)\n score -= 15\n \n # Check ARC criteria (legacy format)\n arc_section = re.search(r'##\\s*7\\.\\s*ARC\\s*Verification\\s*Criteria(.+?)(?=##|$)', content, re.DOTALL | re.IGNORECASE)\n if arc_section:\n arc_content = arc_section.group(1)\n criteria_count = len(re.findall(r'ARC_[A-Z]+_\\d+:', arc_content))\n if criteria_count < 3:\n errors.append(f'Only {criteria_count} testable ARC criteria found (minimum 3 required)')\n score -= 15\n else:\n errors.append('ARC Verification Criteria section is empty or malformed')\n score -= 20\n\n# Check for placeholder text (both formats)\nplaceholder_patterns = [\n (r'\\[Agent:', 'Contains [Agent: placeholder'),\n (r'\\[TODO', 'Contains [TODO] placeholder'),\n (r'\\[FILL', 'Contains [FILL] placeholder'),\n (r'\\[TBD\\]', 'Contains [TBD] placeholder'),\n (r'\\[INSERT', 'Contains [INSERT] placeholder')\n]\nfor pattern, msg in placeholder_patterns:\n if re.search(pattern, content, re.IGNORECASE):\n errors.append(msg)\n score -= 20\n break\n\n# Calculate final validation\noutputs['valid'] = (score >= 70 and len(errors) == 0)\noutputs['score'] = max(0, score)\noutputs['errors'] = errors\noutputs['warnings'] = warnings\noutputs['node_id'] = node_id\noutputs['spec_path'] = str(spec_path)\noutputs['format'] = spec_format"
}
]
}
{
"name": "tracker-scan",
"version": "0.7.0",
"description": "Extracts NodeID statuses and WorkGroup assignments from the KnowzCode tracker.",
"parameters": [],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\ntext = Path('knowzcode/knowzcode_tracker.md').read_text()\nrows = []\nfor line in text.splitlines():\n if line.startswith('|') and '`' in line:\n cols = [c.strip() for c in line.strip('|').split('|')]\n if len(cols) >= 9 and cols[2] != 'Node ID':\n rows.append({'status': cols[0], 'workgroup_id': cols[1], 'node_id': cols[2].strip('`'), 'notes': cols[8]})\noutputs['rows'] = rows\n"
}
]
}
{
"name": "tracker-update",
"version": "0.7.0",
"description": "Applies validated updates to knowzcode/knowzcode_tracker.md while preserving table structure.",
"parameters": [
{
"name": "updates",
"type": "array",
"items": {
"type": "object",
"properties": {
"node_id": {"type": "string"},
"status": {"type": "string"},
"workgroup_id": {"type": "string"},
"notes": {"type": "string"}
},
"required": ["node_id"]
},
"required": true
}
],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\npath = Path('knowzcode/knowzcode_tracker.md')\ntext = path.read_text()\nlines = text.splitlines()\nheader_idx = next(i for i, line in enumerate(lines) if line.startswith('| Status |'))\ntable = lines[header_idx:]\nrows = [line for line in table if line.startswith('|')]\nupdates = {u['node_id']: u for u in inputs['updates']}\nnew_rows = []\nfor row in rows:\n parts = [p.strip() for p in row.strip('|').split('|')]\n if not parts or parts[2] == 'Node ID':\n new_rows.append(row)\n continue\n node_id = parts[2].strip('`')\n if node_id in updates:\n upd = updates[node_id]\n status = upd.get('status', parts[0].strip())\n workgroup = upd.get('workgroup_id', parts[1].strip())\n notes = upd.get('notes', parts[8].strip())\n new_row = f\"| {status} | {workgroup} | `{node_id}` | {parts[3]} | {parts[4]} | {parts[5]} | {parts[6]} | {parts[7]} | {notes} |\"\n new_rows.append(new_row)\n updates.pop(node_id)\n else:\n new_rows.append(row)\nif updates:\n missing = ', '.join(sorted(updates.keys()))\n raise ValueError(f\"NodeIDs {missing} not found in tracker table\")\nlines[header_idx:] = new_rows + lines[header_idx + len(rows):]\npath.write_text('\\n'.join(lines) + '\\n')"
}
]
}
{
"name": "validate-installation",
"version": "0.7.0",
"description": "Validates that KnowzCode installation completed successfully with required directories and files",
"parameters": [],
"actions": [
{
"type": "python",
"code": "from pathlib import Path\nimport json\n\n# Check for knowzcode directory (the primary installation target)\nknowzcode_dir = Path('knowzcode')\nerrors = []\nwarnings = []\n\n# Check directory exists\nif not knowzcode_dir.exists():\n errors.append('knowzcode/ directory not found')\n outputs['valid'] = False\n outputs['errors'] = errors\n outputs['warnings'] = warnings\n outputs['commands_count'] = 0\n outputs['skills_count'] = 0\n outputs['agents_count'] = 0\n exit()\n\n# Check required knowzcode files\nrequired_files = [\n 'knowzcode_loop.md',\n 'knowzcode_tracker.md',\n 'knowzcode_project.md',\n 'knowzcode_architecture.md'\n]\n\nfor required_file in required_files:\n if not (knowzcode_dir / required_file).exists():\n errors.append(f'Missing required file: knowzcode/{required_file}')\n\n# Check required subdirectories\nrequired_dirs = [\n 'specs',\n 'workgroups',\n 'prompts'\n]\n\nfor subdir in required_dirs:\n if not (knowzcode_dir / subdir).exists():\n warnings.append(f'Missing directory: knowzcode/{subdir}')\n\n# Check .claude directory for commands/agents (plugin or local installation)\nclaude_dir = Path('.claude')\ncommands_count = 0\nskills_count = 0\nagents_count = 0\n\nif claude_dir.exists():\n if (claude_dir / 'commands').exists():\n commands_count = len(list((claude_dir / 'commands').glob('*.md')))\n if (claude_dir / 'skills').exists():\n skills_count = len(list((claude_dir / 'skills').glob('*.json')))\n if (claude_dir / 'agents').exists():\n agents_count = len(list((claude_dir / 'agents').glob('*.md')))\n if (claude_dir / 'subagents').exists():\n agents_count += len(list((claude_dir / 'subagents').glob('*.yaml')))\n\n# Also check top-level commands/skills/agents (plugin installation)\nif Path('commands').exists():\n commands_count = max(commands_count, len(list(Path('commands').glob('*.md'))))\nif Path('skills').exists():\n skills_count = max(skills_count, len(list(Path('skills').glob('*.json'))))\nif Path('agents').exists():\n agents_count = max(agents_count, len(list(Path('agents').glob('*.md'))))\n\n# Expected minimums\nif commands_count < 5:\n warnings.append(f'Expected at least 5 commands, found {commands_count}')\nif agents_count < 10:\n warnings.append(f'Expected at least 10 agents, found {agents_count}')\n\noutputs['valid'] = len(errors) == 0\noutputs['errors'] = errors\noutputs['warnings'] = warnings\noutputs['commands_count'] = commands_count\noutputs['skills_count'] = skills_count\noutputs['agents_count'] = agents_count"
}
]
}

Sorry, the diff of this file is too big to display