{"_id":"@alkdev/taskgraph","_rev":"2-0a56773af62680ff6a16662556bfda4e","name":"@alkdev/taskgraph","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@alkdev/taskgraph","version":"0.0.1","keywords":["taskgraph","dag","critical-path","risk-analysis","graphology"],"license":"MIT OR Apache-2.0","_id":"@alkdev/taskgraph@0.0.1","maintainers":[{"name":"alkdev","email":"admin@alk.dev"}],"dist":{"shasum":"2deadf59b897e533c10224c52bdffd74e052d544","tarball":"https://registry.npmjs.org/@alkdev/taskgraph/-/taskgraph-0.0.1.tgz","fileCount":8,"integrity":"sha512-U1EehRUXU1sTjHVgwOumU6EeIWsHHBoY5oxehs1iEZF05EO8uh+GaZfY6M5H0G2wzbSy7qw/exSq2DijWT0xwg==","signatures":[{"sig":"MEQCIBedllm7NlLDjln/UtJojuVa42h3GgX0UvJf031txAlEAiBVzTIZgzDXXhwoqrc7fvBgb8Z8yfUEVxXg816OwH9H8g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":431630},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"a9e087ea135cb6c7774bd7670a1cbfc25c0f34ad","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsup","build:tsc":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"alkdev","email":"admin@alk.dev"},"_npmVersion":"11.11.0","description":"Task graph library — directed acyclic graph analysis, risk scoring, and YAML frontmatter for task management","directories":{},"_nodeVersion":"25.8.1","dependencies":{"yaml":"^2.8.3","graphology":"^0.26.0","graphology-dag":"^0.4.1","@alkdev/typebox":"^0.34.49","graphology-metrics":"^2.4.0","graphology-operators":"^1.6.1","graphology-components":"^1.5.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^3.1.0","typescript":"^5.7.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^3.2.4"},"_npmOperationalInternal":{"tmp":"tmp/taskgraph_0.0.1_1777328684632_0.19617979347438208","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@alkdev/taskgraph","version":"0.0.2","description":"Task graph library — directed acyclic graph analysis, risk scoring, and YAML frontmatter for task management","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","build:tsc":"tsc","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","lint":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["taskgraph","dag","critical-path","risk-analysis","graphology"],"license":"MIT OR Apache-2.0","dependencies":{"@alkdev/typebox":"^0.34.49","graphology":"^0.26.0","graphology-components":"^1.5.4","graphology-dag":"^0.4.1","graphology-metrics":"^2.4.0","graphology-operators":"^1.6.1","yaml":"^2.8.3"},"devDependencies":{"@types/node":"^22.0.0","@vitest/coverage-v8":"^3.2.4","tsup":"^8.5.1","typescript":"^5.7.0","vitest":"^3.1.0"},"engines":{"node":">=18.0.0"},"gitHead":"b7871215c2173b76e39a3f8572ea51e91a758dec","_id":"@alkdev/taskgraph@0.0.2","_nodeVersion":"25.8.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-YwKit2CiNe32NHl/+WEr3Hw/o+DsJWe3MDN6Nz5RK4IyUiOZYAtaffFlTbZNlQosM64Pl9kRgsQnRG2b9ikr/g==","shasum":"2e8b05770aa83ecdd06475ce59f6a9c8cb8b64d6","tarball":"https://registry.npmjs.org/@alkdev/taskgraph/-/taskgraph-0.0.2.tgz","fileCount":8,"unpackedSize":433254,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC+945YTQpYzIc1pZjRti5Sp2kWLfa94rcKmEojom4fSwIgJeoHyejOmTqeoBkVcmlpIbZ49cJTMwjwDXhgBm/TZAw="}]},"_npmUser":{"name":"alkdev","email":"admin@alk.dev"},"directories":{},"maintainers":[{"name":"alkdev","email":"admin@alk.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/taskgraph_0.0.2_1777367639128_0.5561692143440828"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-27T22:24:44.510Z","modified":"2026-04-28T09:13:59.383Z","0.0.1":"2026-04-27T22:24:44.770Z","0.0.2":"2026-04-28T09:13:59.271Z"},"license":"MIT OR Apache-2.0","keywords":["taskgraph","dag","critical-path","risk-analysis","graphology"],"description":"Task graph library — directed acyclic graph analysis, risk scoring, and YAML frontmatter for task management","maintainers":[{"name":"alkdev","email":"admin@alk.dev"}],"readme":"# @alkdev/taskgraph\n\nDirected acyclic graph analysis, risk scoring, and YAML frontmatter parsing for task management.\n\nBuilt on [graphology](https://github.com/graphology/graphology) — pure TypeScript, no native addons, works in Node.js / Deno / Bun.\n\n## Install\n\n```sh\nnpm install @alkdev/taskgraph\n```\n\n## Quick Start\n\n```ts\nimport { TaskGraph, parallelGroups, criticalPath } from '@alkdev/taskgraph';\n\nconst graph = TaskGraph.fromTasks([\n  { id: 'design', name: 'Design API', dependsOn: [], risk: 'low', scope: 'narrow' },\n  { id: 'impl', name: 'Implement', dependsOn: ['design'], risk: 'medium', scope: 'moderate' },\n  { id: 'test', name: 'Write tests', dependsOn: ['impl'], risk: 'low', scope: 'narrow' },\n  { id: 'docs', name: 'Write docs', dependsOn: ['design'], risk: 'trivial', scope: 'narrow' },\n]);\n\nconst groups = parallelGroups(graph);\n// [['design'], ['impl', 'docs'], ['test']]\n\nconst path = criticalPath(graph);\n// ['design', 'impl', 'test']\n```\n\n## TaskGraph\n\nThe primary data structure. Wraps a graphology `DirectedGraph` with validation and typed access.\n\n### Construction\n\n```ts\n// From task inputs (convenience — edges created from dependsOn)\nconst g1 = TaskGraph.fromTasks([...tasks]);\n\n// From explicit tasks + edges (per-edge qualityRetention)\nconst g2 = TaskGraph.fromRecords([...tasks], [...edges]);\n\n// From serialized data (round-trip with export())\nconst data = g1.export();\nconst g3 = TaskGraph.fromJSON(data);\n\n// Incremental building\nconst g4 = new TaskGraph();\ng4.addTask('a', { name: 'Task A' });\ng4.addTask('b', { name: 'Task B' });\ng4.addDependency('a', 'b'); // a → b (a is prerequisite)\n```\n\n### Queries\n\n```ts\ngraph.topologicalOrder();     // string[] — prerequisite → dependent order\ngraph.dependencies('impl');    // ['design'] — prerequisites of impl\ngraph.dependents('design');    // ['impl', 'docs'] — dependents of design\ngraph.hasCycles();             // boolean\ngraph.findCycles();           // string[][] — cycle paths\ngraph.taskCount();             // number\ngraph.getTask('design');       // TaskGraphNodeAttributes | undefined\n```\n\n### Validation\n\n```ts\ngraph.validate();        // AnyValidationError[] — combined schema + graph\ngraph.validateSchema();   // ValidationError[] — per-field TypeBox validation\ngraph.validateGraph();    // GraphValidationError[] — cycles, dangling refs\n```\n\n### Mutation\n\n```ts\ngraph.removeTask('id');\ngraph.removeDependency('prereq', 'dependent');\ngraph.updateTask('id', { risk: 'high' });\ngraph.updateEdgeAttributes('prereq', 'dependent', { qualityRetention: 0.8 });\n```\n\n### Export\n\n```ts\nconst data = graph.export();      // TaskGraphSerialized (graphology JSON)\nconst json = JSON.stringify(graph); // uses toJSON() alias\n```\n\n## Analysis Functions\n\nAll analysis functions take a `TaskGraph` instance as their first argument.\n\n### Critical Path\n\n```ts\nimport { criticalPath, weightedCriticalPath } from '@alkdev/taskgraph';\n\ncriticalPath(graph); // longest path by edge count\n\nweightedCriticalPath(graph, (id, attrs) => {\n  // custom weight per node\n  return riskWeight(attrs.risk ?? 'medium') * impactWeight(attrs.impact ?? 'isolated');\n});\n```\n\n### Parallel Groups\n\n```ts\nimport { parallelGroups } from '@alkdev/taskgraph';\n\nparallelGroups(graph); // string[][] — tasks at each topological depth\n```\n\n### Bottleneck Analysis\n\n```ts\nimport { bottlenecks } from '@alkdev/taskgraph';\n\nconst scores = bottlenecks(graph);\n// [{ taskId: 'design', score: 0.83 }, ...] — sorted descending\n```\n\n### Risk Analysis\n\n```ts\nimport { riskPath, riskDistribution } from '@alkdev/taskgraph';\n\nriskPath(graph);\n// { path: ['design', 'impl', 'test'], totalRisk: 4.2 }\n\nriskDistribution(graph);\n// { trivial: [...], low: [...], medium: [...], high: [...], critical: [...], unspecified: [...] }\n```\n\n### Expected Value & Workflow Cost\n\n```ts\nimport { calculateTaskEv, workflowCost } from '@alkdev/taskgraph';\n\ncalculateTaskEv(0.8, 3.0, 1.5);\n// { ev: 4.2, pSuccess: 0.8, expectedRetries: 0.25 }\n\nconst result = workflowCost(graph, {\n  propagationMode: 'dag-propagate', // or 'independent'\n  defaultQualityRetention: 0.9,\n  includeCompleted: false,\n});\n// result.tasks  — per-task EV entries\n// result.totalEv — aggregate\n// result.averageEv\n```\n\n### Decomposition\n\n```ts\nimport { shouldDecomposeTask } from '@alkdev/taskgraph';\n\nshouldDecomposeTask({ name: 'Refactor', risk: 'high', scope: 'broad' });\n// { shouldDecompose: true, reasons: ['risk: high — ...', 'scope: broad — ...'] }\n```\n\n### Categorical Numeric Methods\n\n```ts\nimport {\n  scopeCostEstimate, scopeTokenEstimate,\n  riskSuccessProbability, riskWeight,\n  impactWeight, resolveDefaults,\n} from '@alkdev/taskgraph';\n\nscopeCostEstimate('moderate');    // 3.0\nscopeTokenEstimate('broad');      // 6000\nriskSuccessProbability('high');   // 0.65\nriskWeight('high');               // 0.35\nimpactWeight('project');          // 3.0\n\nresolveDefaults({ name: 'Task', risk: 'high' });\n// { scope: 'narrow', risk: 'high', ..., costEstimate: 2.0, ... }\n```\n\n## Frontmatter\n\nParse and serialize YAML frontmatter in markdown files.\n\n```ts\nimport {\n  parseFrontmatter, serializeFrontmatter,\n  parseTaskFile, parseTaskDirectory,\n} from '@alkdev/taskgraph';\n\n// Parse a markdown string with --- frontmatter\nconst task = parseFrontmatter(`---\nid: my-task\nname: My Task\ndependsOn: []\nrisk: medium\n---\nTask body here`);\n\n// Serialize back to markdown\nconst md = serializeFrontmatter(task, 'Task body here');\n\n// File I/O (Node.js only)\nconst task2 = await parseTaskFile('/path/to/task.md');\nconst tasks = await parseTaskDirectory('/path/to/tasks/');\n```\n\n## Schemas & Types\n\nAll schemas are TypeBox schemas and all types are inferred from them.\n\n```ts\nimport type {\n  TaskInput, DependencyEdge,\n  TaskGraphNodeAttributes, TaskGraphEdgeAttributes, TaskGraphSerialized,\n  RiskPathResult, DecomposeResult, WorkflowCostOptions, WorkflowCostResult,\n  EvConfig, EvResult, RiskDistributionResult, ResolvedTaskAttributes,\n} from '@alkdev/taskgraph';\n\nimport type {\n  TaskScope, TaskRisk, TaskImpact, TaskLevel, TaskPriority, TaskStatus,\n} from '@alkdev/taskgraph';\n```\n\n### Enums\n\n```ts\n// Type values (also usable as TypeScript types)\ntype Scope = 'single' | 'narrow' | 'moderate' | 'broad' | 'system';\ntype Risk = 'trivial' | 'low' | 'medium' | 'high' | 'critical';\ntype Impact = 'isolated' | 'component' | 'phase' | 'project';\ntype Level = 'planning' | 'decomposition' | 'implementation' | 'review' | 'research';\ntype Priority = 'low' | 'medium' | 'high' | 'critical';\ntype Status = 'pending' | 'in-progress' | 'completed' | 'failed' | 'blocked';\n```\n\n## Error Classes\n\n```ts\nimport {\n  TaskgraphError,          // base class\n  TaskNotFoundError,        // .taskId\n  CircularDependencyError, // .cycles: string[][]\n  InvalidInputError,        // .field, .message\n  DuplicateNodeError,      // .taskId\n  DuplicateEdgeError,      // .prerequisite, .dependent\n} from '@alkdev/taskgraph';\n```\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT License](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.","readmeFilename":"README.md"}