@seanmars/tospec 0.19.0-beta.8 → 0.21.0
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 +89 -296
- package/README.md +69 -82
- package/assets/dashboard/app.js +11 -0
- package/assets/dashboard/style.css +7 -0
- package/bin/tospec.js +1 -1
- package/dist/cli/index.d.ts +6 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +120 -112
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/config.d.ts +9 -17
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +300 -145
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dashboard.d.ts +57 -99
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +252 -330
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/decision.d.ts +38 -27
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +301 -131
- package/dist/commands/decision.js.map +1 -1
- package/dist/commands/metrics.d.ts +28 -51
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +62 -93
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/shared-output.d.ts +12 -27
- package/dist/commands/shared-output.d.ts.map +1 -1
- package/dist/commands/shared-output.js +22 -45
- package/dist/commands/shared-output.js.map +1 -1
- package/dist/commands/show.d.ts +4 -7
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +23 -11
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.d.ts +34 -58
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +228 -142
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/workflow/index.d.ts +1 -5
- package/dist/commands/workflow/index.d.ts.map +1 -1
- package/dist/commands/workflow/index.js +1 -5
- package/dist/commands/workflow/index.js.map +1 -1
- package/dist/commands/workflow/instructions.d.ts +14 -24
- package/dist/commands/workflow/instructions.d.ts.map +1 -1
- package/dist/commands/workflow/instructions.js +230 -132
- package/dist/commands/workflow/instructions.js.map +1 -1
- package/dist/commands/workflow/new-change.d.ts +2 -5
- package/dist/commands/workflow/new-change.d.ts.map +1 -1
- package/dist/commands/workflow/new-change.js +75 -34
- package/dist/commands/workflow/new-change.js.map +1 -1
- package/dist/commands/workflow/schemas.d.ts +1 -5
- package/dist/commands/workflow/schemas.d.ts.map +1 -1
- package/dist/commands/workflow/schemas.js +6 -17
- package/dist/commands/workflow/schemas.js.map +1 -1
- package/dist/commands/workflow/shared.d.ts +37 -42
- package/dist/commands/workflow/shared.d.ts.map +1 -1
- package/dist/commands/workflow/shared.js +23 -54
- package/dist/commands/workflow/shared.js.map +1 -1
- package/dist/commands/workflow/status.d.ts +7 -17
- package/dist/commands/workflow/status.d.ts.map +1 -1
- package/dist/commands/workflow/status.js +57 -72
- package/dist/commands/workflow/status.js.map +1 -1
- package/dist/commands/workflow/templates.d.ts +8 -8
- package/dist/commands/workflow/templates.d.ts.map +1 -1
- package/dist/commands/workflow/templates.js +32 -46
- package/dist/commands/workflow/templates.js.map +1 -1
- package/dist/core/archive.d.ts +33 -31
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +322 -284
- package/dist/core/archive.js.map +1 -1
- package/dist/core/artifact-graph/graph.d.ts +25 -42
- package/dist/core/artifact-graph/graph.d.ts.map +1 -1
- package/dist/core/artifact-graph/graph.js +45 -63
- package/dist/core/artifact-graph/graph.js.map +1 -1
- package/dist/core/artifact-graph/index.d.ts +1 -1
- package/dist/core/artifact-graph/index.d.ts.map +1 -1
- package/dist/core/artifact-graph/index.js +1 -1
- package/dist/core/artifact-graph/index.js.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +54 -120
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +129 -111
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
- package/dist/core/artifact-graph/outputs.d.ts +9 -23
- package/dist/core/artifact-graph/outputs.d.ts.map +1 -1
- package/dist/core/artifact-graph/outputs.js +45 -38
- package/dist/core/artifact-graph/outputs.js.map +1 -1
- package/dist/core/artifact-graph/resolver.d.ts +36 -81
- package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
- package/dist/core/artifact-graph/resolver.js +60 -101
- package/dist/core/artifact-graph/resolver.js.map +1 -1
- package/dist/core/artifact-graph/schema.d.ts +0 -6
- package/dist/core/artifact-graph/schema.d.ts.map +1 -1
- package/dist/core/artifact-graph/schema.js +7 -32
- package/dist/core/artifact-graph/schema.js.map +1 -1
- package/dist/core/artifact-graph/state.d.ts +1 -8
- package/dist/core/artifact-graph/state.d.ts.map +1 -1
- package/dist/core/artifact-graph/state.js +2 -17
- package/dist/core/artifact-graph/state.js.map +1 -1
- package/dist/core/artifact-graph/stub-detection.d.ts +6 -14
- package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -1
- package/dist/core/artifact-graph/stub-detection.js +13 -16
- package/dist/core/artifact-graph/stub-detection.js.map +1 -1
- package/dist/core/artifact-graph/types.d.ts +4 -0
- package/dist/core/artifact-graph/types.d.ts.map +1 -1
- package/dist/core/artifact-graph/types.js +46 -11
- package/dist/core/artifact-graph/types.js.map +1 -1
- package/dist/core/available-tools.d.ts +3 -12
- package/dist/core/available-tools.d.ts.map +1 -1
- package/dist/core/available-tools.js +4 -13
- package/dist/core/available-tools.js.map +1 -1
- package/dist/core/change-metadata/schema.d.ts +1 -1
- package/dist/core/change-metadata/schema.d.ts.map +1 -1
- package/dist/core/change-metadata/schema.js +10 -7
- package/dist/core/change-metadata/schema.js.map +1 -1
- package/dist/core/change-presenter.d.ts +16 -27
- package/dist/core/change-presenter.d.ts.map +1 -1
- package/dist/core/change-presenter.js +53 -53
- package/dist/core/change-presenter.js.map +1 -1
- package/dist/core/change-status-policy.d.ts +4 -8
- package/dist/core/change-status-policy.d.ts.map +1 -1
- package/dist/core/change-status-policy.js +9 -17
- package/dist/core/change-status-policy.js.map +1 -1
- package/dist/core/codex-metrics.d.ts +25 -45
- package/dist/core/codex-metrics.d.ts.map +1 -1
- package/dist/core/codex-metrics.js +44 -88
- package/dist/core/codex-metrics.js.map +1 -1
- package/dist/core/codex-residue.d.ts +14 -15
- package/dist/core/codex-residue.d.ts.map +1 -1
- package/dist/core/codex-residue.js +18 -22
- package/dist/core/codex-residue.js.map +1 -1
- package/dist/core/command-generation/adapters/claude.d.ts +2 -9
- package/dist/core/command-generation/adapters/claude.d.ts.map +1 -1
- package/dist/core/command-generation/adapters/claude.js +2 -12
- package/dist/core/command-generation/adapters/claude.js.map +1 -1
- package/dist/core/command-generation/adapters/index.d.ts +1 -9
- package/dist/core/command-generation/adapters/index.d.ts.map +1 -1
- package/dist/core/command-generation/adapters/index.js +1 -9
- package/dist/core/command-generation/adapters/index.js.map +1 -1
- package/dist/core/command-generation/generator.d.ts +0 -17
- package/dist/core/command-generation/generator.d.ts.map +1 -1
- package/dist/core/command-generation/generator.js +0 -17
- package/dist/core/command-generation/generator.js.map +1 -1
- package/dist/core/command-generation/index.d.ts +2 -5
- package/dist/core/command-generation/index.d.ts.map +1 -1
- package/dist/core/command-generation/index.js +0 -9
- package/dist/core/command-generation/index.js.map +1 -1
- package/dist/core/command-generation/types.d.ts +10 -36
- package/dist/core/command-generation/types.d.ts.map +1 -1
- package/dist/core/command-generation/types.js +0 -6
- package/dist/core/command-generation/types.js.map +1 -1
- package/dist/core/command-generation/yaml.d.ts +3 -18
- package/dist/core/command-generation/yaml.d.ts.map +1 -1
- package/dist/core/command-generation/yaml.js +5 -23
- package/dist/core/command-generation/yaml.js.map +1 -1
- package/dist/core/config-prompts.d.ts +2 -4
- package/dist/core/config-prompts.d.ts.map +1 -1
- package/dist/core/config-prompts.js +2 -7
- package/dist/core/config-prompts.js.map +1 -1
- package/dist/core/config-schema.d.ts +7 -41
- package/dist/core/config-schema.d.ts.map +1 -1
- package/dist/core/config-schema.js +35 -74
- package/dist/core/config-schema.js.map +1 -1
- package/dist/core/config.d.ts +25 -49
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +22 -45
- package/dist/core/config.js.map +1 -1
- package/dist/core/dashboard-activity.d.ts +7 -9
- package/dist/core/dashboard-activity.d.ts.map +1 -1
- package/dist/core/dashboard-activity.js +34 -25
- package/dist/core/dashboard-activity.js.map +1 -1
- package/dist/core/dashboard-data.d.ts +35 -22
- package/dist/core/dashboard-data.d.ts.map +1 -1
- package/dist/core/dashboard-data.js +57 -72
- package/dist/core/dashboard-data.js.map +1 -1
- package/dist/core/global-config.d.ts +24 -53
- package/dist/core/global-config.d.ts.map +1 -1
- package/dist/core/global-config.js +38 -67
- package/dist/core/global-config.js.map +1 -1
- package/dist/core/init.d.ts +12 -28
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +93 -169
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +95 -41
- package/dist/core/list.js.map +1 -1
- package/dist/core/local-server.d.ts +41 -83
- package/dist/core/local-server.d.ts.map +1 -1
- package/dist/core/local-server.js +53 -98
- package/dist/core/local-server.js.map +1 -1
- package/dist/core/markdown-render.d.ts +15 -23
- package/dist/core/markdown-render.d.ts.map +1 -1
- package/dist/core/markdown-render.js +25 -34
- package/dist/core/markdown-render.js.map +1 -1
- package/dist/core/migrate.d.ts +19 -16
- package/dist/core/migrate.d.ts.map +1 -1
- package/dist/core/migrate.js +162 -136
- package/dist/core/migrate.js.map +1 -1
- package/dist/core/parsers/change-parser.d.ts +7 -10
- package/dist/core/parsers/change-parser.d.ts.map +1 -1
- package/dist/core/parsers/change-parser.js +48 -56
- package/dist/core/parsers/change-parser.js.map +1 -1
- package/dist/core/parsers/markdown-parser.d.ts +8 -9
- package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
- package/dist/core/parsers/markdown-parser.js +23 -30
- package/dist/core/parsers/markdown-parser.js.map +1 -1
- package/dist/core/parsers/requirement-blocks.d.ts +43 -15
- package/dist/core/parsers/requirement-blocks.d.ts.map +1 -1
- package/dist/core/parsers/requirement-blocks.js +142 -70
- package/dist/core/parsers/requirement-blocks.js.map +1 -1
- package/dist/core/parsers/requirement-text.d.ts +73 -79
- package/dist/core/parsers/requirement-text.d.ts.map +1 -1
- package/dist/core/parsers/requirement-text.js +137 -79
- package/dist/core/parsers/requirement-text.js.map +1 -1
- package/dist/core/parsers/spec-structure.d.ts.map +1 -1
- package/dist/core/parsers/spec-structure.js +10 -6
- package/dist/core/parsers/spec-structure.js.map +1 -1
- package/dist/core/profiles.d.ts +3 -10
- package/dist/core/profiles.d.ts.map +1 -1
- package/dist/core/profiles.js +5 -12
- package/dist/core/profiles.js.map +1 -1
- package/dist/core/project-config.d.ts +43 -44
- package/dist/core/project-config.d.ts.map +1 -1
- package/dist/core/project-config.js +107 -82
- package/dist/core/project-config.js.map +1 -1
- package/dist/core/project-layout.d.ts +9 -17
- package/dist/core/project-layout.d.ts.map +1 -1
- package/dist/core/project-layout.js +16 -26
- package/dist/core/project-layout.js.map +1 -1
- package/dist/core/root-selection.d.ts +8 -14
- package/dist/core/root-selection.d.ts.map +1 -1
- package/dist/core/root-selection.js +3 -6
- package/dist/core/root-selection.js.map +1 -1
- package/dist/core/rules.d.ts.map +1 -1
- package/dist/core/rules.js +2 -3
- package/dist/core/rules.js.map +1 -1
- package/dist/core/schema-names.d.ts +16 -0
- package/dist/core/schema-names.d.ts.map +1 -0
- package/dist/core/schema-names.js +16 -0
- package/dist/core/schema-names.js.map +1 -0
- package/dist/core/schemas/base.schema.d.ts.map +1 -1
- package/dist/core/schemas/base.schema.js +6 -12
- package/dist/core/schemas/base.schema.js.map +1 -1
- package/dist/core/schemas/change.schema.d.ts +8 -0
- package/dist/core/schemas/change.schema.d.ts.map +1 -1
- package/dist/core/schemas/change.schema.js +41 -10
- package/dist/core/schemas/change.schema.js.map +1 -1
- package/dist/core/shared/index.d.ts +2 -7
- package/dist/core/shared/index.d.ts.map +1 -1
- package/dist/core/shared/index.js +2 -7
- package/dist/core/shared/index.js.map +1 -1
- package/dist/core/shared/rules-generation.d.ts +5 -15
- package/dist/core/shared/rules-generation.d.ts.map +1 -1
- package/dist/core/shared/rules-generation.js +33 -37
- package/dist/core/shared/rules-generation.js.map +1 -1
- package/dist/core/shared/skill-generation.d.ts +28 -43
- package/dist/core/shared/skill-generation.d.ts.map +1 -1
- package/dist/core/shared/skill-generation.js +82 -51
- package/dist/core/shared/skill-generation.js.map +1 -1
- package/dist/core/shared/tool-detection.d.ts +35 -76
- package/dist/core/shared/tool-detection.d.ts.map +1 -1
- package/dist/core/shared/tool-detection.js +73 -93
- package/dist/core/shared/tool-detection.js.map +1 -1
- package/dist/core/skill-metrics.d.ts +36 -63
- package/dist/core/skill-metrics.d.ts.map +1 -1
- package/dist/core/skill-metrics.js +34 -73
- package/dist/core/skill-metrics.js.map +1 -1
- package/dist/core/spec-presenter.d.ts.map +1 -1
- package/dist/core/spec-presenter.js +5 -10
- package/dist/core/spec-presenter.js.map +1 -1
- package/dist/core/specs-apply.d.ts +16 -31
- package/dist/core/specs-apply.d.ts.map +1 -1
- package/dist/core/specs-apply.js +146 -195
- package/dist/core/specs-apply.js.map +1 -1
- package/dist/core/templates/fragments/interview.d.ts +2 -6
- package/dist/core/templates/fragments/interview.d.ts.map +1 -1
- package/dist/core/templates/fragments/interview.js +2 -6
- package/dist/core/templates/fragments/interview.js.map +1 -1
- package/dist/core/templates/fragments/next-step.d.ts +4 -8
- package/dist/core/templates/fragments/next-step.d.ts.map +1 -1
- package/dist/core/templates/fragments/next-step.js +4 -8
- package/dist/core/templates/fragments/next-step.js.map +1 -1
- package/dist/core/templates/fragments/validate.d.ts +13 -0
- package/dist/core/templates/fragments/validate.d.ts.map +1 -0
- package/dist/core/templates/fragments/validate.js +13 -0
- package/dist/core/templates/fragments/validate.js.map +1 -0
- package/dist/core/templates/fragments/verify.d.ts +9 -12
- package/dist/core/templates/fragments/verify.d.ts.map +1 -1
- package/dist/core/templates/fragments/verify.js +9 -12
- package/dist/core/templates/fragments/verify.js.map +1 -1
- package/dist/core/templates/index.d.ts +0 -6
- package/dist/core/templates/index.d.ts.map +1 -1
- package/dist/core/templates/index.js +0 -7
- package/dist/core/templates/index.js.map +1 -1
- package/dist/core/templates/skill-templates.d.ts +1 -5
- package/dist/core/templates/skill-templates.d.ts.map +1 -1
- package/dist/core/templates/skill-templates.js +0 -5
- package/dist/core/templates/skill-templates.js.map +1 -1
- package/dist/core/templates/types.d.ts +3 -7
- package/dist/core/templates/types.d.ts.map +1 -1
- package/dist/core/templates/types.js +0 -3
- package/dist/core/templates/types.js.map +1 -1
- package/dist/core/templates/workflows/apply.d.ts +3 -9
- package/dist/core/templates/workflows/apply.d.ts.map +1 -1
- package/dist/core/templates/workflows/apply.js +11 -13
- package/dist/core/templates/workflows/apply.js.map +1 -1
- package/dist/core/templates/workflows/archive.d.ts +0 -6
- package/dist/core/templates/workflows/archive.d.ts.map +1 -1
- package/dist/core/templates/workflows/archive.js +16 -5
- package/dist/core/templates/workflows/archive.js.map +1 -1
- package/dist/core/templates/workflows/decision.js +3 -3
- package/dist/core/templates/workflows/decision.js.map +1 -1
- package/dist/core/templates/workflows/explore.js +1 -1
- package/dist/core/templates/workflows/grill.d.ts.map +1 -1
- package/dist/core/templates/workflows/grill.js +0 -2
- package/dist/core/templates/workflows/grill.js.map +1 -1
- package/dist/core/templates/workflows/issue.d.ts +0 -6
- package/dist/core/templates/workflows/issue.d.ts.map +1 -1
- package/dist/core/templates/workflows/issue.js +3 -2
- package/dist/core/templates/workflows/issue.js.map +1 -1
- package/dist/core/templates/workflows/propose.d.ts +0 -6
- package/dist/core/templates/workflows/propose.d.ts.map +1 -1
- package/dist/core/templates/workflows/propose.js +2 -2
- package/dist/core/templates/workflows/propose.js.map +1 -1
- package/dist/core/templates/workflows/sync.d.ts +2 -8
- package/dist/core/templates/workflows/sync.d.ts.map +1 -1
- package/dist/core/templates/workflows/sync.js +4 -3
- package/dist/core/templates/workflows/sync.js.map +1 -1
- package/dist/core/templates/workflows/update.d.ts +0 -6
- package/dist/core/templates/workflows/update.d.ts.map +1 -1
- package/dist/core/templates/workflows/update.js +9 -2
- package/dist/core/templates/workflows/update.js.map +1 -1
- package/dist/core/update.d.ts +10 -36
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +59 -126
- package/dist/core/update.js.map +1 -1
- package/dist/core/user-state-migration.d.ts +13 -15
- package/dist/core/user-state-migration.d.ts.map +1 -1
- package/dist/core/user-state-migration.js +30 -23
- package/dist/core/user-state-migration.js.map +1 -1
- package/dist/core/validation/constants.d.ts +4 -10
- package/dist/core/validation/constants.d.ts.map +1 -1
- package/dist/core/validation/constants.js +25 -25
- package/dist/core/validation/constants.js.map +1 -1
- package/dist/core/validation/prose-length.d.ts +15 -0
- package/dist/core/validation/prose-length.d.ts.map +1 -0
- package/dist/core/validation/prose-length.js +29 -0
- package/dist/core/validation/prose-length.js.map +1 -0
- package/dist/core/validation/purpose-placeholder.d.ts +9 -16
- package/dist/core/validation/purpose-placeholder.d.ts.map +1 -1
- package/dist/core/validation/purpose-placeholder.js +30 -44
- package/dist/core/validation/purpose-placeholder.js.map +1 -1
- package/dist/core/validation/section-validator.d.ts +4 -4
- package/dist/core/validation/section-validator.d.ts.map +1 -1
- package/dist/core/validation/section-validator.js +30 -12
- package/dist/core/validation/section-validator.js.map +1 -1
- package/dist/core/validation/task-numbering.d.ts +6 -3
- package/dist/core/validation/task-numbering.d.ts.map +1 -1
- package/dist/core/validation/task-numbering.js +23 -11
- package/dist/core/validation/task-numbering.js.map +1 -1
- package/dist/core/validation/types.d.ts +18 -0
- package/dist/core/validation/types.d.ts.map +1 -1
- package/dist/core/validation/types.js +12 -1
- package/dist/core/validation/types.js.map +1 -1
- package/dist/core/validation/validator.d.ts +42 -68
- package/dist/core/validation/validator.d.ts.map +1 -1
- package/dist/core/validation/validator.js +474 -285
- package/dist/core/validation/validator.js.map +1 -1
- package/dist/prompts/searchable-multi-select.d.ts +3 -8
- package/dist/prompts/searchable-multi-select.d.ts.map +1 -1
- package/dist/prompts/searchable-multi-select.js +16 -39
- package/dist/prompts/searchable-multi-select.js.map +1 -1
- package/dist/utils/change-metadata.d.ts +11 -50
- package/dist/utils/change-metadata.d.ts.map +1 -1
- package/dist/utils/change-metadata.js +48 -67
- package/dist/utils/change-metadata.js.map +1 -1
- package/dist/utils/change-utils.d.ts +24 -76
- package/dist/utils/change-utils.d.ts.map +1 -1
- package/dist/utils/change-utils.js +95 -142
- package/dist/utils/change-utils.js.map +1 -1
- package/dist/utils/file-lock.d.ts +39 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +149 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/dist/utils/file-system.d.ts +12 -32
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +41 -45
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +7 -11
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +11 -11
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/interactive.d.ts +4 -9
- package/dist/utils/interactive.d.ts.map +1 -1
- package/dist/utils/interactive.js +2 -4
- package/dist/utils/interactive.js.map +1 -1
- package/dist/utils/item-discovery.d.ts +10 -20
- package/dist/utils/item-discovery.d.ts.map +1 -1
- package/dist/utils/item-discovery.js +31 -55
- package/dist/utils/item-discovery.js.map +1 -1
- package/dist/utils/link.d.ts +9 -18
- package/dist/utils/link.d.ts.map +1 -1
- package/dist/utils/link.js +9 -18
- package/dist/utils/link.js.map +1 -1
- package/dist/utils/requirement-diff.d.ts +13 -23
- package/dist/utils/requirement-diff.d.ts.map +1 -1
- package/dist/utils/requirement-diff.js +13 -23
- package/dist/utils/requirement-diff.js.map +1 -1
- package/dist/utils/spec-files.d.ts +7 -20
- package/dist/utils/spec-files.d.ts.map +1 -1
- package/dist/utils/spec-files.js +26 -51
- package/dist/utils/spec-files.js.map +1 -1
- package/dist/utils/task-progress.d.ts +11 -9
- package/dist/utils/task-progress.d.ts.map +1 -1
- package/dist/utils/task-progress.js +53 -32
- package/dist/utils/task-progress.js.map +1 -1
- package/dist/utils/timestamp.d.ts +5 -8
- package/dist/utils/timestamp.d.ts.map +1 -1
- package/dist/utils/timestamp.js +5 -8
- package/dist/utils/timestamp.js.map +1 -1
- package/package.json +2 -3
- package/schemas/issue/schema.yaml +8 -1
- package/schemas/issue/templates/spec.md +20 -3
- package/schemas/sdd/schema.yaml +20 -1
- package/schemas/sdd/templates/spec.md +20 -3
|
@@ -1,40 +1,29 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool Detection Utilities
|
|
3
|
-
*
|
|
4
|
-
* Shared utilities for detecting tool configurations and version status.
|
|
5
|
-
*/
|
|
6
1
|
import path from 'path';
|
|
7
2
|
import * as fs from 'fs';
|
|
8
3
|
import { AI_TOOLS, LEGACY_WORKFLOW_RULE_FILENAME, TOOL_RULES_SUBDIR, WORKFLOW_RULE_FILENAME, } from '../config.js';
|
|
9
4
|
import { ALL_WORKFLOWS, workflowSkillDirName } from './skill-generation.js';
|
|
10
5
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
6
|
+
* Skill directories `tospec init` creates, derived from the one workflow registry.
|
|
7
|
+
* Project-scope skills can't be nested, so they live flat and prefixed at
|
|
8
|
+
* `<tool.skillsDir>/skills/tospec-<workflow>/SKILL.md`.
|
|
14
9
|
*/
|
|
15
10
|
export const SKILL_NAMES = ALL_WORKFLOWS.map(workflowSkillDirName);
|
|
16
11
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `.agents/skills/`. verify was folded into apply; reconcile was renamed back
|
|
20
|
-
* to sync, so its dir must go rather than sit beside the new one.
|
|
12
|
+
* Skill directories tospec used to create but no longer does; removed on
|
|
13
|
+
* init/update so an upgrade leaves no orphans.
|
|
21
14
|
*
|
|
22
|
-
* A name
|
|
23
|
-
* runs on every init/update, so an overlap
|
|
24
|
-
* just wrote — silently, surfacing later as a missing skill rather than an error.
|
|
25
|
-
* That is why `tospec-sync` came out of this list when the reconcile rename was
|
|
26
|
-
* reverted, instead of `tospec-reconcile` simply being appended.
|
|
15
|
+
* A name WORKFLOW_DEFS generates must never appear here: removeLegacySkillDirs
|
|
16
|
+
* runs on every init/update, so an overlap deletes the skill the run just wrote.
|
|
27
17
|
*/
|
|
28
18
|
export const LEGACY_SKILL_DIRS = ['tospec-verify', 'tospec-reconcile'];
|
|
29
19
|
/**
|
|
30
|
-
* Removes
|
|
31
|
-
*
|
|
32
|
-
*
|
|
20
|
+
* Removes each directory that exists and reports how many went. Errors are
|
|
21
|
+
* swallowed per directory: one that cannot be removed must not abort an init
|
|
22
|
+
* that has otherwise succeeded.
|
|
33
23
|
*/
|
|
34
|
-
|
|
24
|
+
async function removeDirs(dirs) {
|
|
35
25
|
let removed = 0;
|
|
36
|
-
for (const
|
|
37
|
-
const dir = path.join(skillsDir, dirName);
|
|
26
|
+
for (const dir of dirs) {
|
|
38
27
|
try {
|
|
39
28
|
if (fs.existsSync(dir)) {
|
|
40
29
|
await fs.promises.rm(dir, { recursive: true, force: true });
|
|
@@ -42,49 +31,69 @@ export async function removeLegacySkillDirs(skillsDir) {
|
|
|
42
31
|
}
|
|
43
32
|
}
|
|
44
33
|
catch {
|
|
45
|
-
//
|
|
34
|
+
// Best effort, per the note above.
|
|
46
35
|
}
|
|
47
36
|
}
|
|
48
37
|
return removed;
|
|
49
38
|
}
|
|
39
|
+
/** Idempotent: safe when the legacy dirs do not exist. */
|
|
40
|
+
export async function removeLegacySkillDirs(skillsDir) {
|
|
41
|
+
return removeDirs(LEGACY_SKILL_DIRS.map((dirName) => path.join(skillsDir, dirName)));
|
|
42
|
+
}
|
|
50
43
|
/**
|
|
51
|
-
* Removes the
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
44
|
+
* Removes the skill directories for workflows the active profile does not select.
|
|
45
|
+
*
|
|
46
|
+
* Shared by `init` and `update`: agents load skills from the skill directory, so
|
|
47
|
+
* a run that prunes only `.claude/commands/tosx/` leaves excluded workflows
|
|
48
|
+
* loadable.
|
|
49
|
+
*
|
|
50
|
+
* ALL_WORKFLOWS and the directory naming are derived here rather than passed in,
|
|
51
|
+
* since a caller supplying either is a copy that can fall behind WORKFLOW_DEFS.
|
|
59
52
|
*/
|
|
60
|
-
export async function
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
53
|
+
export async function removeUnselectedSkillDirs(skillsDir, desiredWorkflows) {
|
|
54
|
+
const desiredSet = new Set(desiredWorkflows);
|
|
55
|
+
const unselected = ALL_WORKFLOWS
|
|
56
|
+
.filter((workflow) => !desiredSet.has(workflow))
|
|
57
|
+
.map(workflowSkillDirName)
|
|
58
|
+
.filter((dirName) => dirName)
|
|
59
|
+
.map((dirName) => path.join(skillsDir, dirName));
|
|
60
|
+
return removeDirs([...unselected, ...staleGeneratedSkillDirs(skillsDir)]);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* `tospec-*` skill directories this version does not generate but an earlier
|
|
64
|
+
* one did — a workflow renamed or dropped since. Recognised by the
|
|
65
|
+
* `generatedBy` frontmatter: a hand-written skill carries none and is left
|
|
66
|
+
* alone, because nothing else would ever restore it.
|
|
67
|
+
*/
|
|
68
|
+
function staleGeneratedSkillDirs(skillsDir) {
|
|
69
|
+
let entries;
|
|
70
|
+
try {
|
|
71
|
+
entries = fs.readdirSync(skillsDir, { withFileTypes: true });
|
|
76
72
|
}
|
|
77
|
-
|
|
73
|
+
catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const known = new Set([...SKILL_NAMES, ...LEGACY_SKILL_DIRS]);
|
|
77
|
+
return entries
|
|
78
|
+
.filter((entry) => entry.isDirectory() && entry.name.startsWith('tospec-') && !known.has(entry.name))
|
|
79
|
+
.map((entry) => path.join(skillsDir, entry.name))
|
|
80
|
+
.filter((dir) => extractGeneratedByVersion(path.join(dir, 'SKILL.md')) !== null);
|
|
78
81
|
}
|
|
79
82
|
/**
|
|
80
|
-
*
|
|
83
|
+
* Removes the grouped skill layouts earlier builds wrote, so an upgrade lands at
|
|
84
|
+
* the current flat `<toolBaseDir>/skills/tospec-<workflow>/`. The flat dirs are
|
|
85
|
+
* left alone: the copy loop refreshes them, and retired ones go via
|
|
86
|
+
* removeLegacySkillDirs.
|
|
81
87
|
*/
|
|
88
|
+
export async function removeLegacyToolSkillLayout(toolBaseDir) {
|
|
89
|
+
return removeDirs([
|
|
90
|
+
path.join(toolBaseDir, 'skills', 'tospec'), // grouped: <tool>/skills/tospec/<workflow>
|
|
91
|
+
path.join(toolBaseDir, 'tospec'), // bare: <tool>/tospec/<workflow>
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
82
94
|
export function getToolsWithSkillsDir() {
|
|
83
95
|
return AI_TOOLS.filter((t) => t.skillsDir).map((t) => t.value);
|
|
84
96
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Checks which skill files exist for a tool.
|
|
87
|
-
*/
|
|
88
97
|
export function getToolSkillStatus(projectRoot, toolId) {
|
|
89
98
|
const tool = AI_TOOLS.find((t) => t.value === toolId);
|
|
90
99
|
if (!tool?.skillsDir) {
|
|
@@ -104,36 +113,20 @@ export function getToolSkillStatus(projectRoot, toolId) {
|
|
|
104
113
|
skillCount,
|
|
105
114
|
};
|
|
106
115
|
}
|
|
107
|
-
/**
|
|
108
|
-
* Gets the skill status for all tools with skillsDir configured.
|
|
109
|
-
*/
|
|
110
116
|
export function getToolStates(projectRoot) {
|
|
111
117
|
const states = new Map();
|
|
112
|
-
const
|
|
113
|
-
for (const toolId of toolIds) {
|
|
118
|
+
for (const toolId of getToolsWithSkillsDir()) {
|
|
114
119
|
states.set(toolId, getToolSkillStatus(projectRoot, toolId));
|
|
115
120
|
}
|
|
116
121
|
return states;
|
|
117
122
|
}
|
|
118
|
-
/**
|
|
119
|
-
* Extracts the generatedBy version from a skill file's YAML frontmatter.
|
|
120
|
-
* Returns null if the field is not found or the file doesn't exist.
|
|
121
|
-
*/
|
|
123
|
+
/** Null when the field is absent or the file cannot be read. */
|
|
122
124
|
export function extractGeneratedByVersion(skillFilePath) {
|
|
123
125
|
try {
|
|
124
126
|
if (!fs.existsSync(skillFilePath)) {
|
|
125
127
|
return null;
|
|
126
128
|
}
|
|
127
129
|
const content = fs.readFileSync(skillFilePath, 'utf-8');
|
|
128
|
-
// Look for generatedBy in the YAML frontmatter
|
|
129
|
-
// The file format is:
|
|
130
|
-
// ---
|
|
131
|
-
// ...
|
|
132
|
-
// metadata:
|
|
133
|
-
// author: tospec
|
|
134
|
-
// version: "1.0"
|
|
135
|
-
// generatedBy: "0.23.0"
|
|
136
|
-
// ---
|
|
137
130
|
const generatedByMatch = content.match(/^\s*generatedBy:\s*["']?([^"'\n]+)["']?\s*$/m);
|
|
138
131
|
if (generatedByMatch && generatedByMatch[1]) {
|
|
139
132
|
return generatedByMatch[1].trim();
|
|
@@ -144,9 +137,7 @@ export function extractGeneratedByVersion(skillFilePath) {
|
|
|
144
137
|
return null;
|
|
145
138
|
}
|
|
146
139
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Gets version status for a tool by reading the first available skill file.
|
|
149
|
-
*/
|
|
140
|
+
/** Reads the version from the first skill file the tool has. */
|
|
150
141
|
export function getToolVersionStatus(projectRoot, toolId, currentVersion) {
|
|
151
142
|
const tool = AI_TOOLS.find((t) => t.value === toolId);
|
|
152
143
|
if (!tool?.skillsDir) {
|
|
@@ -160,7 +151,6 @@ export function getToolVersionStatus(projectRoot, toolId, currentVersion) {
|
|
|
160
151
|
}
|
|
161
152
|
const skillsDir = path.join(projectRoot, tool.skillsDir, 'skills');
|
|
162
153
|
let generatedByVersion = null;
|
|
163
|
-
// Find the first skill file that exists and read its version
|
|
164
154
|
for (const skillName of SKILL_NAMES) {
|
|
165
155
|
const skillFile = path.join(skillsDir, skillName, 'SKILL.md');
|
|
166
156
|
if (fs.existsSync(skillFile)) {
|
|
@@ -178,9 +168,6 @@ export function getToolVersionStatus(projectRoot, toolId, currentVersion) {
|
|
|
178
168
|
needsUpdate,
|
|
179
169
|
};
|
|
180
170
|
}
|
|
181
|
-
/**
|
|
182
|
-
* Gets all configured tools in the project.
|
|
183
|
-
*/
|
|
184
171
|
export function getConfiguredTools(projectRoot) {
|
|
185
172
|
return AI_TOOLS
|
|
186
173
|
.filter((t) => t.skillsDir && isToolInstalled(projectRoot, t.value))
|
|
@@ -188,21 +175,14 @@ export function getConfiguredTools(projectRoot) {
|
|
|
188
175
|
}
|
|
189
176
|
/**
|
|
190
177
|
* Whether tospec has been installed into this tool dir, independent of how many
|
|
191
|
-
* skills
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* and the wrong one for `update`/`rules`. A profile that selects no workflows
|
|
196
|
-
* makes `update` remove every `tospec-<workflow>` dir, and while installation was
|
|
197
|
-
* inferred from that same directory count, the run that emptied the dir also
|
|
198
|
-
* erased the only evidence the tool was ever set up: the next `update` reported
|
|
199
|
-
* "No configured tools found" and only `init` could recover. See
|
|
200
|
-
* tospec/decisions/20260916_152000-tool-install-marker-not-skill-count.md
|
|
178
|
+
* skills sit there — the right question for `update`/`rules`, where
|
|
179
|
+
* `getToolSkillStatus().configured` is wrong: a profile selecting no workflows
|
|
180
|
+
* makes `update` remove every skill dir, erasing the evidence the tool was set
|
|
181
|
+
* up. tospec/decisions/20260916_152000-tool-install-marker-not-skill-count.md
|
|
201
182
|
*
|
|
202
|
-
* The workflow rule document is the durable marker: written
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* only, so it proves tospec once touched the dir, not that it still manages it.
|
|
183
|
+
* The workflow rule document is the durable marker: written on every
|
|
184
|
+
* init/update/rules, removed by none. The legacy `rules/tospec/decision.md` is
|
|
185
|
+
* init-only, so it proves tospec once touched the dir, not that it manages it.
|
|
206
186
|
*/
|
|
207
187
|
export function isToolInstalled(projectRoot, toolId) {
|
|
208
188
|
const tool = AI_TOOLS.find((t) => t.value === toolId);
|
|
@@ -211,7 +191,7 @@ export function isToolInstalled(projectRoot, toolId) {
|
|
|
211
191
|
if (getToolSkillStatus(projectRoot, toolId).configured)
|
|
212
192
|
return true;
|
|
213
193
|
// Either spelling: a project last touched before the filename typo was fixed
|
|
214
|
-
//
|
|
194
|
+
// holds the legacy name, which is just as much proof of an install.
|
|
215
195
|
return [WORKFLOW_RULE_FILENAME, LEGACY_WORKFLOW_RULE_FILENAME].some((name) => fs.existsSync(path.join(projectRoot, tool.skillsDir, ...TOOL_RULES_SUBDIR, name)));
|
|
216
196
|
}
|
|
217
197
|
//# sourceMappingURL=tool-detection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-detection.js","sourceRoot":"","sources":["../../../src/core/shared/tool-detection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tool-detection.js","sourceRoot":"","sources":["../../../src/core/shared/tool-detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Skill duration metrics, derived from Claude Code transcripts.
|
|
3
3
|
*
|
|
4
|
-
* There is no tospec-side event to measure
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
4
|
+
* There is no tospec-side event to measure: the CLI is stateless, so it never
|
|
5
|
+
* learns when a workflow starts or ends, and CLI-call telemetry would miss the
|
|
6
|
+
* workflows that barely touch it. Every transcript entry in
|
|
7
|
+
* `<config>/projects/<encoded-cwd>/<session>.jsonl` already carries an
|
|
8
|
+
* `attributionSkill`, so this is a read-only analysis of existing data. The
|
|
9
|
+
* field is recent, so older sessions yield no runs — reported, not hidden.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `attributionSkill` field naming the skill that entry belongs to, so skill
|
|
13
|
-
* timing is a read-only analysis of data that already exists — retroactively,
|
|
14
|
-
* with nothing to install. The cost is that the field is recent: sessions
|
|
15
|
-
* predating it yield no runs, which is reported rather than hidden.
|
|
16
|
-
*
|
|
17
|
-
* Two durations are reported per run because they answer different questions
|
|
18
|
-
* and diverge sharply in conversational workflows:
|
|
11
|
+
* Two durations per run, because they diverge sharply in conversational
|
|
12
|
+
* workflows:
|
|
19
13
|
*
|
|
20
14
|
* - `span` — wall clock, first to last entry. "How long did this take?"
|
|
21
15
|
* - `engaged` — span minus gaps over `idleGapMs`. "How much of that was work?"
|
|
22
16
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* equal. Reporting only one of them would silently answer the other question.
|
|
26
|
-
*
|
|
27
|
-
* Pure parsing/aggregation is split from the directory-reading wrapper so
|
|
28
|
-
* vitest can exercise it without a transcript store on disk.
|
|
17
|
+
* Pure parsing/aggregation is split from the directory-reading wrapper so tests
|
|
18
|
+
* can exercise it without a transcript store on disk.
|
|
29
19
|
*/
|
|
30
20
|
/** Gap above which the user is considered away, excluded from `engaged`. */
|
|
31
21
|
export declare const DEFAULT_IDLE_GAP_MS: number;
|
|
@@ -42,10 +32,9 @@ export interface TranscriptEntry {
|
|
|
42
32
|
skill: string | null;
|
|
43
33
|
}
|
|
44
34
|
/**
|
|
45
|
-
* Which tool a run's timing
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* they carry different confidence.
|
|
35
|
+
* Which tool a run's timing came from. Claude Code's `attributionSkill` is read
|
|
36
|
+
* directly; Codex's is inferred by a heuristic (codex-metrics.ts), so the two
|
|
37
|
+
* carry different confidence and are never combined into one figure.
|
|
49
38
|
*/
|
|
50
39
|
export type MetricsSourceKind = 'claude-code' | 'codex';
|
|
51
40
|
export interface SkillRun {
|
|
@@ -103,8 +92,8 @@ export interface RunGroupingOptions {
|
|
|
103
92
|
/**
|
|
104
93
|
* Claude Code's per-project transcript directory name: the absolute cwd with
|
|
105
94
|
* every non-alphanumeric character replaced by `-`. `D:\workspace\a.b` becomes
|
|
106
|
-
* `D--workspace-a-b`
|
|
107
|
-
*
|
|
95
|
+
* `D--workspace-a-b` — the drive colon and the separator each contribute a dash,
|
|
96
|
+
* so the doubled dash is correct.
|
|
108
97
|
*/
|
|
109
98
|
export declare function encodeProjectDirName(rootPath: string): string;
|
|
110
99
|
export interface TranscriptDirOptions {
|
|
@@ -112,57 +101,46 @@ export interface TranscriptDirOptions {
|
|
|
112
101
|
homedir?: string;
|
|
113
102
|
}
|
|
114
103
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* `~/.claude`. Injectable env/homedir follows global-config.ts so path
|
|
118
|
-
* resolution stays testable.
|
|
104
|
+
* The transcript directory for a project root. `CLAUDE_CONFIG_DIR` is honoured
|
|
105
|
+
* because Claude Code itself does; without it the default is `~/.claude`.
|
|
119
106
|
*/
|
|
120
107
|
export declare function resolveTranscriptDir(rootPath: string, options?: TranscriptDirOptions): string;
|
|
121
108
|
/**
|
|
122
109
|
* Collapses the two names one workflow is recorded under — the slash command
|
|
123
|
-
* (`tosx:apply`) and the skill (`tospec-apply`) — onto the workflow id
|
|
124
|
-
*
|
|
110
|
+
* (`tosx:apply`) and the skill (`tospec-apply`) — onto the workflow id, so its
|
|
111
|
+
* history is one row rather than two.
|
|
125
112
|
*/
|
|
126
113
|
export declare function normalizeSkillName(raw: string): string;
|
|
127
114
|
export declare function isWorkflowSkill(skill: string): boolean;
|
|
128
115
|
/**
|
|
129
116
|
* Parses one `.jsonl` transcript into timestamped entries, sorted by time.
|
|
130
117
|
* Malformed lines are skipped rather than fatal: transcripts are an append-only
|
|
131
|
-
* log written by another process and can be torn at the tail
|
|
132
|
-
* is live.
|
|
118
|
+
* log written by another process and can be torn at the tail.
|
|
133
119
|
*/
|
|
134
120
|
export declare function parseTranscript(text: string): TranscriptEntry[];
|
|
135
121
|
/**
|
|
136
|
-
* Groups one session's entries into runs.
|
|
122
|
+
* Groups one session's entries into runs. Two rules carry the design:
|
|
137
123
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* - A **different skill** does end a run. Grouping all of one skill's entries
|
|
145
|
-
* by min/max instead would make an A → B → A sequence count B's elapsed time
|
|
146
|
-
* inside A's engaged total. Splitting keeps run windows disjoint, at the cost
|
|
147
|
-
* of reporting a re-entered skill as several runs.
|
|
124
|
+
* - An **unattributed** entry does not end a run. Tool results and user messages
|
|
125
|
+
* carry no `attributionSkill`, so treating them as boundaries shatters a
|
|
126
|
+
* 30-minute `apply` into fragments.
|
|
127
|
+
* - A **different skill** does end a run. Grouping by min/max instead would
|
|
128
|
+
* count B's elapsed time inside A's engaged total for an A → B → A sequence.
|
|
129
|
+
* The cost is reporting a re-entered skill as several runs.
|
|
148
130
|
*
|
|
149
131
|
* A run is additionally split at any internal gap over `splitGapMs`.
|
|
150
132
|
*/
|
|
151
133
|
export declare function buildRuns(entries: TranscriptEntry[], session: string, options?: RunGroupingOptions): SkillRun[];
|
|
152
134
|
/**
|
|
153
|
-
* The composite key
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* module) — one definition of "row" everywhere a skill and its source must
|
|
157
|
-
* be kept apart rather than merged.
|
|
135
|
+
* The composite key for one report row: a skill under one source. The frontend
|
|
136
|
+
* reproduces this format in JS (it cannot import a TS module), so keep the two
|
|
137
|
+
* in step.
|
|
158
138
|
*/
|
|
159
139
|
export declare function skillRowKey(skill: string, source: MetricsSourceKind): string;
|
|
160
140
|
/**
|
|
161
|
-
* Aggregates runs per skill-and-source pair,
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* Code's attribution and Codex's heuristic one carry different confidence and
|
|
165
|
-
* must stay distinguishable everywhere a skill is reported.
|
|
141
|
+
* Aggregates runs per skill-and-source pair, by total engaged time descending.
|
|
142
|
+
* Grouping by source keeps a skill run under both tools from summing into one
|
|
143
|
+
* figure, since the two carry different confidence.
|
|
166
144
|
*/
|
|
167
145
|
export declare function aggregateRuns(runs: SkillRun[]): SkillAggregate[];
|
|
168
146
|
export interface CollectMetricsOptions extends RunGroupingOptions, TranscriptDirOptions {
|
|
@@ -172,14 +150,9 @@ export interface CollectMetricsOptions extends RunGroupingOptions, TranscriptDir
|
|
|
172
150
|
/**
|
|
173
151
|
* Reads every transcript for a project root and derives skill timings.
|
|
174
152
|
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* without this function deciding for it.
|
|
179
|
-
*
|
|
180
|
-
* A missing transcript directory is a reportable state (`available: false`),
|
|
181
|
-
* not an error: the project may simply never have been opened in Claude Code,
|
|
182
|
-
* and the caller renders that far better than a stack trace.
|
|
153
|
+
* No filtering by skill name: every skill found is reported, and `workflow` on
|
|
154
|
+
* each aggregate labels tospec's own. A missing transcript directory is a
|
|
155
|
+
* reportable state (`available: false`), not an error.
|
|
183
156
|
*/
|
|
184
157
|
export declare function collectSkillMetrics(rootPath: string, options?: CollectMetricsOptions): Promise<SkillMetrics>;
|
|
185
158
|
//# sourceMappingURL=skill-metrics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-metrics.d.ts","sourceRoot":"","sources":["../../src/core/skill-metrics.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"skill-metrics.d.ts","sourceRoot":"","sources":["../../src/core/skill-metrics.ts"],"names":[],"mappings":"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"}
|