artifact-chain-assistant 0.8.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/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +20 -0
- package/.claude-plugin/plugin.json +11 -0
- package/.codex-plugin/plugin.json +27 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +26 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +19 -0
- package/.github/pull_request_template.md +14 -0
- package/.github/workflows/ci.yml +23 -0
- package/CHANGELOG.md +196 -0
- package/CODE_OF_CONDUCT.md +11 -0
- package/CONTRIBUTING.md +24 -0
- package/EXTENDED-ARTIFACT-CATALOG.md +312 -0
- package/EXTENDED-ARTIFACT-CATALOG.zh-CN.md +289 -0
- package/INSTALL.md +1340 -0
- package/LICENSE +186 -0
- package/NOTICE +18 -0
- package/README.md +426 -0
- package/README.zh-CN.md +409 -0
- package/SECURITY.md +19 -0
- package/adapters/claude/.claude-plugin/plugin.json +11 -0
- package/adapters/claude/EXTENDED-ARTIFACT-CATALOG.md +312 -0
- package/adapters/claude/EXTENDED-ARTIFACT-CATALOG.zh-CN.md +289 -0
- package/adapters/claude/INSTALL.md +1340 -0
- package/adapters/claude/agent-methods/catalog.yaml +260 -0
- package/adapters/claude/bin/version-lock-audit.sh +21 -0
- package/adapters/claude/bin/version-lock-refresh.sh +21 -0
- package/adapters/claude/commands/version-lock-audit.md +9 -0
- package/adapters/claude/commands/version-lock-refresh.md +9 -0
- package/adapters/claude/compatibility.json +9 -0
- package/adapters/claude/hooks/hooks.json +16 -0
- package/adapters/claude/hooks/version-lock-stop.mjs +77 -0
- package/adapters/claude/schemas/artifact-workflow-profile.schema.json +72 -0
- package/adapters/claude/scripts/batch-merge.mjs +276 -0
- package/adapters/claude/scripts/batch-split.mjs +184 -0
- package/adapters/claude/scripts/check-workflow-profile.mjs +64 -0
- package/adapters/claude/scripts/doctor.mjs +44 -0
- package/adapters/claude/scripts/lib/artifact-graph-runtime.mjs +189 -0
- package/adapters/claude/scripts/lib/compatibility-policy.mjs +435 -0
- package/adapters/claude/scripts/lib/inline-yaml-parser.mjs +216 -0
- package/adapters/claude/scripts/lib/method-registry-version.mjs +7 -0
- package/adapters/claude/scripts/lib/workflow-profile.mjs +645 -0
- package/adapters/claude/scripts/run-artifact-workflow.mjs +366 -0
- package/adapters/claude/skills/artifact-audit/SKILL.md +80 -0
- package/adapters/claude/skills/artifact-batch/SKILL.md +115 -0
- package/adapters/claude/skills/artifact-chain-bootstrap/SKILL.md +343 -0
- package/adapters/claude/skills/artifact-chain-maintainer/SKILL.md +167 -0
- package/adapters/claude/skills/artifact-generate/SKILL.md +89 -0
- package/adapters/claude/skills/artifact-repair/SKILL.md +124 -0
- package/adapters/claude/skills/artifact-review/SKILL.md +122 -0
- package/adapters/claude/skills/artifact-workflow-worker/SKILL.md +90 -0
- package/adapters/claude/skills/prd-feature/SKILL.md +68 -0
- package/adapters/claude/skills/prd-feature/author/SKILL.md +92 -0
- package/adapters/claude/skills/prd-feature/references/compose.md +43 -0
- package/adapters/claude/skills/prd-feature/references/inspect.md +94 -0
- package/adapters/claude/skills/prd-feature/references/validate.md +65 -0
- package/adapters/claude/skills/prd-feature/repair/SKILL.md +135 -0
- package/adapters/claude/skills/prd-feature/review/SKILL.md +134 -0
- package/adapters/claude/skills/scenario-script/SKILL.md +76 -0
- package/adapters/claude/skills/scenario-script/author/SKILL.md +111 -0
- package/adapters/claude/skills/scenario-script/references/compose.md +43 -0
- package/adapters/claude/skills/scenario-script/references/inspect.md +105 -0
- package/adapters/claude/skills/scenario-script/references/validate.md +72 -0
- package/adapters/claude/skills/scenario-script/repair/SKILL.md +135 -0
- package/adapters/claude/skills/scenario-script/review/SKILL.md +137 -0
- package/adapters/claude/skills/where-am-i/SKILL.md +233 -0
- package/adapters/claude/templates/README.md +159 -0
- package/adapters/claude/templates/core/decision/review-checklist.md +35 -0
- package/adapters/claude/templates/core/decision/starter.md +66 -0
- package/adapters/claude/templates/core/design/review-checklist.md +41 -0
- package/adapters/claude/templates/core/design/starter.md +84 -0
- package/adapters/claude/templates/core/e2e_test/review-checklist.md +43 -0
- package/adapters/claude/templates/core/e2e_test/starter.md +70 -0
- package/adapters/claude/templates/core/feature/review-checklist.md +29 -0
- package/adapters/claude/templates/core/feature/starter.md +43 -0
- package/adapters/claude/templates/core/scenario/review-checklist.md +29 -0
- package/adapters/claude/templates/core/scenario/starter.md +57 -0
- package/adapters/claude/templates/core/test/review-checklist.md +37 -0
- package/adapters/claude/templates/core/test/starter.md +70 -0
- package/adapters/claude/templates/extended/ADOPTION-GUIDE.md +263 -0
- package/adapters/claude/templates/extended/README.md +261 -0
- package/adapters/claude/templates/extended/agent/agent_skill/review-checklist.md +51 -0
- package/adapters/claude/templates/extended/agent/agent_skill/starter.md +133 -0
- package/adapters/claude/templates/extended/agent/hook_policy/review-checklist.md +58 -0
- package/adapters/claude/templates/extended/agent/hook_policy/starter.md +134 -0
- package/adapters/claude/templates/extended/agent/prompt_packet/review-checklist.md +54 -0
- package/adapters/claude/templates/extended/agent/prompt_packet/starter.md +106 -0
- package/adapters/claude/templates/extended/contracts/api_contract/review-checklist.md +43 -0
- package/adapters/claude/templates/extended/contracts/api_contract/starter.md +92 -0
- package/adapters/claude/templates/extended/contracts/batch_job_contract/review-checklist.md +82 -0
- package/adapters/claude/templates/extended/contracts/batch_job_contract/starter.md +158 -0
- package/adapters/claude/templates/extended/contracts/cli_contract/review-checklist.md +43 -0
- package/adapters/claude/templates/extended/contracts/cli_contract/starter.md +93 -0
- package/adapters/claude/templates/extended/contracts/data_contract/review-checklist.md +45 -0
- package/adapters/claude/templates/extended/contracts/data_contract/starter.md +88 -0
- package/adapters/claude/templates/extended/contracts/integration_contract/review-checklist.md +77 -0
- package/adapters/claude/templates/extended/contracts/integration_contract/starter.md +158 -0
- package/adapters/claude/templates/extended/contracts/ipc_contract/review-checklist.md +78 -0
- package/adapters/claude/templates/extended/contracts/ipc_contract/starter.md +214 -0
- package/adapters/claude/templates/extended/contracts/report_contract/review-checklist.md +61 -0
- package/adapters/claude/templates/extended/contracts/report_contract/starter.md +97 -0
- package/adapters/claude/templates/extended/contracts/ui_contract/review-checklist.md +70 -0
- package/adapters/claude/templates/extended/contracts/ui_contract/starter.md +150 -0
- package/adapters/claude/templates/extended/domain/database_migration/review-checklist.md +51 -0
- package/adapters/claude/templates/extended/domain/database_migration/starter.md +115 -0
- package/adapters/claude/templates/extended/domain/domain_model/review-checklist.md +43 -0
- package/adapters/claude/templates/extended/domain/domain_model/starter.md +83 -0
- package/adapters/claude/templates/extended/governance/oss_compliance/review-checklist.md +51 -0
- package/adapters/claude/templates/extended/governance/oss_compliance/starter.md +84 -0
- package/adapters/claude/templates/extended/governance/publish_skill/review-checklist.md +58 -0
- package/adapters/claude/templates/extended/governance/publish_skill/starter.md +172 -0
- package/adapters/claude/templates/extended/governance/release_policy/review-checklist.md +57 -0
- package/adapters/claude/templates/extended/governance/release_policy/starter.md +131 -0
- package/adapters/claude/templates/extended/ops/deployment_manifest/review-checklist.md +51 -0
- package/adapters/claude/templates/extended/ops/deployment_manifest/starter.md +117 -0
- package/adapters/claude/templates/extended/ops/migration_plan/review-checklist.md +63 -0
- package/adapters/claude/templates/extended/ops/migration_plan/starter.md +117 -0
- package/adapters/claude/templates/extended/ops/performance_budget/review-checklist.md +50 -0
- package/adapters/claude/templates/extended/ops/performance_budget/starter.md +117 -0
- package/adapters/claude/templates/extended/ops/runbook/review-checklist.md +51 -0
- package/adapters/claude/templates/extended/ops/runbook/starter.md +101 -0
- package/adapters/claude/templates/extended/ops/security_review/review-checklist.md +56 -0
- package/adapters/claude/templates/extended/ops/security_review/starter.md +125 -0
- package/adapters/codex/.codex-plugin/plugin.json +27 -0
- package/adapters/codex/EXTENDED-ARTIFACT-CATALOG.md +312 -0
- package/adapters/codex/EXTENDED-ARTIFACT-CATALOG.zh-CN.md +289 -0
- package/adapters/codex/INSTALL.md +1340 -0
- package/adapters/codex/agent-methods/catalog.yaml +260 -0
- package/adapters/codex/compatibility.json +9 -0
- package/adapters/codex/schemas/artifact-workflow-profile.schema.json +72 -0
- package/adapters/codex/scripts/batch-merge.mjs +276 -0
- package/adapters/codex/scripts/batch-split.mjs +184 -0
- package/adapters/codex/scripts/check-workflow-profile.mjs +64 -0
- package/adapters/codex/scripts/doctor.mjs +44 -0
- package/adapters/codex/scripts/lib/artifact-graph-runtime.mjs +189 -0
- package/adapters/codex/scripts/lib/compatibility-policy.mjs +435 -0
- package/adapters/codex/scripts/lib/inline-yaml-parser.mjs +216 -0
- package/adapters/codex/scripts/lib/method-registry-version.mjs +7 -0
- package/adapters/codex/scripts/lib/workflow-profile.mjs +645 -0
- package/adapters/codex/scripts/run-artifact-workflow.mjs +366 -0
- package/adapters/codex/skills/artifact-audit/SKILL.md +80 -0
- package/adapters/codex/skills/artifact-batch/SKILL.md +115 -0
- package/adapters/codex/skills/artifact-chain-bootstrap/SKILL.md +343 -0
- package/adapters/codex/skills/artifact-chain-maintainer/SKILL.md +167 -0
- package/adapters/codex/skills/artifact-generate/SKILL.md +89 -0
- package/adapters/codex/skills/artifact-repair/SKILL.md +124 -0
- package/adapters/codex/skills/artifact-review/SKILL.md +122 -0
- package/adapters/codex/skills/artifact-workflow-worker/SKILL.md +90 -0
- package/adapters/codex/skills/prd-feature/SKILL.md +68 -0
- package/adapters/codex/skills/prd-feature/author/SKILL.md +92 -0
- package/adapters/codex/skills/prd-feature/references/compose.md +43 -0
- package/adapters/codex/skills/prd-feature/references/inspect.md +94 -0
- package/adapters/codex/skills/prd-feature/references/validate.md +65 -0
- package/adapters/codex/skills/prd-feature/repair/SKILL.md +135 -0
- package/adapters/codex/skills/prd-feature/review/SKILL.md +134 -0
- package/adapters/codex/skills/scenario-script/SKILL.md +76 -0
- package/adapters/codex/skills/scenario-script/author/SKILL.md +111 -0
- package/adapters/codex/skills/scenario-script/references/compose.md +43 -0
- package/adapters/codex/skills/scenario-script/references/inspect.md +105 -0
- package/adapters/codex/skills/scenario-script/references/validate.md +72 -0
- package/adapters/codex/skills/scenario-script/repair/SKILL.md +135 -0
- package/adapters/codex/skills/scenario-script/review/SKILL.md +137 -0
- package/adapters/codex/skills/where-am-i/SKILL.md +233 -0
- package/adapters/codex/templates/README.md +159 -0
- package/adapters/codex/templates/core/decision/review-checklist.md +35 -0
- package/adapters/codex/templates/core/decision/starter.md +66 -0
- package/adapters/codex/templates/core/design/review-checklist.md +41 -0
- package/adapters/codex/templates/core/design/starter.md +84 -0
- package/adapters/codex/templates/core/e2e_test/review-checklist.md +43 -0
- package/adapters/codex/templates/core/e2e_test/starter.md +70 -0
- package/adapters/codex/templates/core/feature/review-checklist.md +29 -0
- package/adapters/codex/templates/core/feature/starter.md +43 -0
- package/adapters/codex/templates/core/scenario/review-checklist.md +29 -0
- package/adapters/codex/templates/core/scenario/starter.md +57 -0
- package/adapters/codex/templates/core/test/review-checklist.md +37 -0
- package/adapters/codex/templates/core/test/starter.md +70 -0
- package/adapters/codex/templates/extended/ADOPTION-GUIDE.md +263 -0
- package/adapters/codex/templates/extended/README.md +261 -0
- package/adapters/codex/templates/extended/agent/agent_skill/review-checklist.md +51 -0
- package/adapters/codex/templates/extended/agent/agent_skill/starter.md +133 -0
- package/adapters/codex/templates/extended/agent/hook_policy/review-checklist.md +58 -0
- package/adapters/codex/templates/extended/agent/hook_policy/starter.md +134 -0
- package/adapters/codex/templates/extended/agent/prompt_packet/review-checklist.md +54 -0
- package/adapters/codex/templates/extended/agent/prompt_packet/starter.md +106 -0
- package/adapters/codex/templates/extended/contracts/api_contract/review-checklist.md +43 -0
- package/adapters/codex/templates/extended/contracts/api_contract/starter.md +92 -0
- package/adapters/codex/templates/extended/contracts/batch_job_contract/review-checklist.md +82 -0
- package/adapters/codex/templates/extended/contracts/batch_job_contract/starter.md +158 -0
- package/adapters/codex/templates/extended/contracts/cli_contract/review-checklist.md +43 -0
- package/adapters/codex/templates/extended/contracts/cli_contract/starter.md +93 -0
- package/adapters/codex/templates/extended/contracts/data_contract/review-checklist.md +45 -0
- package/adapters/codex/templates/extended/contracts/data_contract/starter.md +88 -0
- package/adapters/codex/templates/extended/contracts/integration_contract/review-checklist.md +77 -0
- package/adapters/codex/templates/extended/contracts/integration_contract/starter.md +158 -0
- package/adapters/codex/templates/extended/contracts/ipc_contract/review-checklist.md +78 -0
- package/adapters/codex/templates/extended/contracts/ipc_contract/starter.md +214 -0
- package/adapters/codex/templates/extended/contracts/report_contract/review-checklist.md +61 -0
- package/adapters/codex/templates/extended/contracts/report_contract/starter.md +97 -0
- package/adapters/codex/templates/extended/contracts/ui_contract/review-checklist.md +70 -0
- package/adapters/codex/templates/extended/contracts/ui_contract/starter.md +150 -0
- package/adapters/codex/templates/extended/domain/database_migration/review-checklist.md +51 -0
- package/adapters/codex/templates/extended/domain/database_migration/starter.md +115 -0
- package/adapters/codex/templates/extended/domain/domain_model/review-checklist.md +43 -0
- package/adapters/codex/templates/extended/domain/domain_model/starter.md +83 -0
- package/adapters/codex/templates/extended/governance/oss_compliance/review-checklist.md +51 -0
- package/adapters/codex/templates/extended/governance/oss_compliance/starter.md +84 -0
- package/adapters/codex/templates/extended/governance/publish_skill/review-checklist.md +58 -0
- package/adapters/codex/templates/extended/governance/publish_skill/starter.md +172 -0
- package/adapters/codex/templates/extended/governance/release_policy/review-checklist.md +57 -0
- package/adapters/codex/templates/extended/governance/release_policy/starter.md +131 -0
- package/adapters/codex/templates/extended/ops/deployment_manifest/review-checklist.md +51 -0
- package/adapters/codex/templates/extended/ops/deployment_manifest/starter.md +117 -0
- package/adapters/codex/templates/extended/ops/migration_plan/review-checklist.md +63 -0
- package/adapters/codex/templates/extended/ops/migration_plan/starter.md +117 -0
- package/adapters/codex/templates/extended/ops/performance_budget/review-checklist.md +50 -0
- package/adapters/codex/templates/extended/ops/performance_budget/starter.md +117 -0
- package/adapters/codex/templates/extended/ops/runbook/review-checklist.md +51 -0
- package/adapters/codex/templates/extended/ops/runbook/starter.md +101 -0
- package/adapters/codex/templates/extended/ops/security_review/review-checklist.md +56 -0
- package/adapters/codex/templates/extended/ops/security_review/starter.md +125 -0
- package/agent-methods/catalog.yaml +260 -0
- package/compatibility.json +9 -0
- package/package.json +85 -0
- package/runtime/claude/version-lock-stop.mjs +77 -0
- package/schemas/artifact-workflow-profile.schema.json +72 -0
- package/scripts/batch-merge.mjs +276 -0
- package/scripts/batch-split.mjs +184 -0
- package/scripts/build-adapters.mjs +195 -0
- package/scripts/build-runtime-bundles.mjs +134 -0
- package/scripts/check-compatibility.mjs +19 -0
- package/scripts/check-method-registry.mjs +461 -0
- package/scripts/check-templates.mjs +348 -0
- package/scripts/check-workflow-profile.mjs +64 -0
- package/scripts/doctor.mjs +44 -0
- package/scripts/install-git-hooks.mjs +21 -0
- package/scripts/lib/artifact-graph-runtime.mjs +189 -0
- package/scripts/lib/compatibility-policy.mjs +435 -0
- package/scripts/lib/inline-yaml-parser.mjs +216 -0
- package/scripts/lib/method-registry-version.mjs +7 -0
- package/scripts/lib/workflow-profile.mjs +645 -0
- package/scripts/run-artifact-workflow.mjs +366 -0
- package/scripts/sync-skills.mjs +149 -0
- package/skills-src/artifact-audit/SKILL.md +80 -0
- package/skills-src/artifact-batch/SKILL.md +115 -0
- package/skills-src/artifact-chain-bootstrap/SKILL.md +343 -0
- package/skills-src/artifact-chain-maintainer/SKILL.md +167 -0
- package/skills-src/artifact-generate/SKILL.md +89 -0
- package/skills-src/artifact-repair/SKILL.md +124 -0
- package/skills-src/artifact-review/SKILL.md +122 -0
- package/skills-src/artifact-workflow-worker/SKILL.md +90 -0
- package/skills-src/prd-feature/SKILL.md +68 -0
- package/skills-src/prd-feature/author/SKILL.md +92 -0
- package/skills-src/prd-feature/references/compose.md +43 -0
- package/skills-src/prd-feature/references/inspect.md +94 -0
- package/skills-src/prd-feature/references/validate.md +65 -0
- package/skills-src/prd-feature/repair/SKILL.md +135 -0
- package/skills-src/prd-feature/review/SKILL.md +134 -0
- package/skills-src/scenario-script/SKILL.md +76 -0
- package/skills-src/scenario-script/author/SKILL.md +111 -0
- package/skills-src/scenario-script/references/compose.md +43 -0
- package/skills-src/scenario-script/references/inspect.md +105 -0
- package/skills-src/scenario-script/references/validate.md +72 -0
- package/skills-src/scenario-script/repair/SKILL.md +135 -0
- package/skills-src/scenario-script/review/SKILL.md +137 -0
- package/skills-src/where-am-i/SKILL.md.tpl +233 -0
- package/templates/README.md +159 -0
- package/templates/claude/marketplace.json.tpl +20 -0
- package/templates/claude/plugin.json.tpl +11 -0
- package/templates/claude/settings.json.tpl +16 -0
- package/templates/codex/marketplace.json.tpl +20 -0
- package/templates/codex/plugin.json.tpl +27 -0
- package/templates/core/decision/review-checklist.md +35 -0
- package/templates/core/decision/starter.md +66 -0
- package/templates/core/design/review-checklist.md +41 -0
- package/templates/core/design/starter.md +84 -0
- package/templates/core/e2e_test/review-checklist.md +43 -0
- package/templates/core/e2e_test/starter.md +70 -0
- package/templates/core/feature/review-checklist.md +29 -0
- package/templates/core/feature/starter.md +43 -0
- package/templates/core/scenario/review-checklist.md +29 -0
- package/templates/core/scenario/starter.md +57 -0
- package/templates/core/test/review-checklist.md +37 -0
- package/templates/core/test/starter.md +70 -0
- package/templates/extended/ADOPTION-GUIDE.md +263 -0
- package/templates/extended/README.md +261 -0
- package/templates/extended/agent/agent_skill/review-checklist.md +51 -0
- package/templates/extended/agent/agent_skill/starter.md +133 -0
- package/templates/extended/agent/hook_policy/review-checklist.md +58 -0
- package/templates/extended/agent/hook_policy/starter.md +134 -0
- package/templates/extended/agent/prompt_packet/review-checklist.md +54 -0
- package/templates/extended/agent/prompt_packet/starter.md +106 -0
- package/templates/extended/contracts/api_contract/review-checklist.md +43 -0
- package/templates/extended/contracts/api_contract/starter.md +92 -0
- package/templates/extended/contracts/batch_job_contract/review-checklist.md +82 -0
- package/templates/extended/contracts/batch_job_contract/starter.md +158 -0
- package/templates/extended/contracts/cli_contract/review-checklist.md +43 -0
- package/templates/extended/contracts/cli_contract/starter.md +93 -0
- package/templates/extended/contracts/data_contract/review-checklist.md +45 -0
- package/templates/extended/contracts/data_contract/starter.md +88 -0
- package/templates/extended/contracts/integration_contract/review-checklist.md +77 -0
- package/templates/extended/contracts/integration_contract/starter.md +158 -0
- package/templates/extended/contracts/ipc_contract/review-checklist.md +78 -0
- package/templates/extended/contracts/ipc_contract/starter.md +214 -0
- package/templates/extended/contracts/report_contract/review-checklist.md +61 -0
- package/templates/extended/contracts/report_contract/starter.md +97 -0
- package/templates/extended/contracts/ui_contract/review-checklist.md +70 -0
- package/templates/extended/contracts/ui_contract/starter.md +150 -0
- package/templates/extended/domain/database_migration/review-checklist.md +51 -0
- package/templates/extended/domain/database_migration/starter.md +115 -0
- package/templates/extended/domain/domain_model/review-checklist.md +43 -0
- package/templates/extended/domain/domain_model/starter.md +83 -0
- package/templates/extended/governance/oss_compliance/review-checklist.md +51 -0
- package/templates/extended/governance/oss_compliance/starter.md +84 -0
- package/templates/extended/governance/publish_skill/review-checklist.md +58 -0
- package/templates/extended/governance/publish_skill/starter.md +172 -0
- package/templates/extended/governance/release_policy/review-checklist.md +57 -0
- package/templates/extended/governance/release_policy/starter.md +131 -0
- package/templates/extended/ops/deployment_manifest/review-checklist.md +51 -0
- package/templates/extended/ops/deployment_manifest/starter.md +117 -0
- package/templates/extended/ops/migration_plan/review-checklist.md +63 -0
- package/templates/extended/ops/migration_plan/starter.md +117 -0
- package/templates/extended/ops/performance_budget/review-checklist.md +50 -0
- package/templates/extended/ops/performance_budget/starter.md +117 -0
- package/templates/extended/ops/runbook/review-checklist.md +51 -0
- package/templates/extended/ops/runbook/starter.md +101 -0
- package/templates/extended/ops/security_review/review-checklist.md +56 -0
- package/templates/extended/ops/security_review/starter.md +125 -0
- package/templates/git-hooks/pre-commit.sh +43 -0
- package/templates/git-hooks/pre-push.sh +22 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// @feature ACA16 @scenario S-49
|
|
2
|
+
// Deterministic batch splitting for artifact review workflows.
|
|
3
|
+
|
|
4
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
5
|
+
import { join, relative, resolve } from 'node:path';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Recursively collect all .md files under a directory.
|
|
9
|
+
*/
|
|
10
|
+
async function collectMarkdownFiles(dir, base) {
|
|
11
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
12
|
+
const files = [];
|
|
13
|
+
|
|
14
|
+
for (const entry of entries) {
|
|
15
|
+
const fullPath = join(dir, entry.name);
|
|
16
|
+
if (entry.isDirectory()) {
|
|
17
|
+
// Skip hidden directories and node_modules
|
|
18
|
+
if (entry.name.startsWith('.') || entry.name === 'node_modules') continue;
|
|
19
|
+
files.push(...await collectMarkdownFiles(fullPath, base));
|
|
20
|
+
} else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
21
|
+
const relativePath = relative(base, fullPath);
|
|
22
|
+
const content = await readFile(fullPath, 'utf8');
|
|
23
|
+
files.push({
|
|
24
|
+
path: relativePath,
|
|
25
|
+
chars: content.length,
|
|
26
|
+
content,
|
|
27
|
+
// For grouping: detect part-*.md files that belong to a batch-*.md
|
|
28
|
+
groupKey: extractGroupKey(entry.name, relativePath),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return files;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Extract a group key for related-file co-location.
|
|
38
|
+
* Files like batch-001-part-1.md, batch-001-part-2.md share the key "batch-001".
|
|
39
|
+
* Standalone files get a unique key based on their path.
|
|
40
|
+
*/
|
|
41
|
+
function extractGroupKey(fileName, relativePath) {
|
|
42
|
+
// Match batch-*.md pattern for grouping parts
|
|
43
|
+
const batchMatch = fileName.match(/^(batch-[^/]+?)(?:-part-\d+)?\.md$/);
|
|
44
|
+
if (batchMatch) {
|
|
45
|
+
return `batch:${batchMatch[1]}`;
|
|
46
|
+
}
|
|
47
|
+
// Each standalone file is its own group
|
|
48
|
+
return `file:${relativePath}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Sort files deterministically by path.
|
|
53
|
+
*/
|
|
54
|
+
function sortFiles(files) {
|
|
55
|
+
return files.sort((a, b) => a.path.localeCompare(b.path));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Build batches from sorted files.
|
|
60
|
+
*
|
|
61
|
+
* Strategy:
|
|
62
|
+
* 1. Group files by groupKey to keep related files together.
|
|
63
|
+
* 2. For each group, if adding the group to the current batch exceeds batch-size,
|
|
64
|
+
* and the current batch is non-empty, flush it and start a new one.
|
|
65
|
+
* 3. If a single group exceeds batch-size, it gets its own batch.
|
|
66
|
+
* 4. Sort groups by their first file's path for determinism.
|
|
67
|
+
*/
|
|
68
|
+
function buildBatches(files, batchSize) {
|
|
69
|
+
// Group files by groupKey
|
|
70
|
+
const groups = new Map();
|
|
71
|
+
for (const file of files) {
|
|
72
|
+
if (!groups.has(file.groupKey)) {
|
|
73
|
+
groups.set(file.groupKey, []);
|
|
74
|
+
}
|
|
75
|
+
groups.get(file.groupKey).push(file);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Sort groups by their first file's path for determinism
|
|
79
|
+
const sortedGroups = [...groups.entries()].sort(([, a], [, b]) =>
|
|
80
|
+
a[0].path.localeCompare(b[0].path)
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const batches = [];
|
|
84
|
+
let currentBatchFiles = [];
|
|
85
|
+
let currentBatchChars = 0;
|
|
86
|
+
|
|
87
|
+
for (const [, groupFiles] of sortedGroups) {
|
|
88
|
+
const groupChars = groupFiles.reduce((sum, f) => sum + f.chars, 0);
|
|
89
|
+
|
|
90
|
+
// If the group alone exceeds batch-size, it gets its own batch
|
|
91
|
+
if (groupChars >= batchSize) {
|
|
92
|
+
// Flush current batch if non-empty
|
|
93
|
+
if (currentBatchFiles.length > 0) {
|
|
94
|
+
batches.push(currentBatchFiles);
|
|
95
|
+
currentBatchFiles = [];
|
|
96
|
+
currentBatchChars = 0;
|
|
97
|
+
}
|
|
98
|
+
// This group is its own batch
|
|
99
|
+
batches.push(groupFiles);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// If adding this group would exceed batch-size, flush current batch
|
|
104
|
+
if (currentBatchChars + groupChars > batchSize && currentBatchFiles.length > 0) {
|
|
105
|
+
batches.push(currentBatchFiles);
|
|
106
|
+
currentBatchFiles = [];
|
|
107
|
+
currentBatchChars = 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Add group to current batch
|
|
111
|
+
currentBatchFiles.push(...groupFiles);
|
|
112
|
+
currentBatchChars += groupChars;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Flush remaining files
|
|
116
|
+
if (currentBatchFiles.length > 0) {
|
|
117
|
+
batches.push(currentBatchFiles);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return batches;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Deterministic batch splitting.
|
|
125
|
+
*
|
|
126
|
+
* @param {string} targetDir - Directory to scan for .md files
|
|
127
|
+
* @param {object} options
|
|
128
|
+
* @param {number} [options.batchSize=40000] - Maximum characters per batch
|
|
129
|
+
* @returns {Promise<Array<{id: string, files: string[], chars: number}>>}
|
|
130
|
+
*/
|
|
131
|
+
export async function batchSplit(targetDir, options = {}) {
|
|
132
|
+
const { batchSize = 40000 } = options;
|
|
133
|
+
const base = resolve(targetDir);
|
|
134
|
+
|
|
135
|
+
// Verify target directory exists
|
|
136
|
+
const targetStat = await stat(base).catch(() => null);
|
|
137
|
+
if (!targetStat || !targetStat.isDirectory()) {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Collect and sort files
|
|
142
|
+
const rawFiles = await collectMarkdownFiles(base, base);
|
|
143
|
+
const files = sortFiles(rawFiles);
|
|
144
|
+
|
|
145
|
+
// Build batches
|
|
146
|
+
const batchArrays = buildBatches(files, batchSize);
|
|
147
|
+
|
|
148
|
+
// Format output
|
|
149
|
+
return batchArrays.map((batchFiles, index) => ({
|
|
150
|
+
id: `batch-${String(index + 1).padStart(3, '0')}`,
|
|
151
|
+
files: batchFiles.map(f => f.path),
|
|
152
|
+
chars: batchFiles.reduce((sum, f) => sum + f.chars, 0),
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// CLI entry point
|
|
157
|
+
const isMain = import.meta.url === `file://${process.argv[1]}`;
|
|
158
|
+
if (isMain) {
|
|
159
|
+
const args = process.argv.slice(2);
|
|
160
|
+
const targetDir = args[0];
|
|
161
|
+
|
|
162
|
+
if (!targetDir) {
|
|
163
|
+
console.error('Usage: node batch-split.mjs <target-dir> [--batch-size N]');
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let batchSize = 40000;
|
|
168
|
+
const sizeIdx = args.indexOf('--batch-size');
|
|
169
|
+
if (sizeIdx !== -1 && args[sizeIdx + 1]) {
|
|
170
|
+
batchSize = parseInt(args[sizeIdx + 1], 10);
|
|
171
|
+
if (isNaN(batchSize) || batchSize <= 0) {
|
|
172
|
+
console.error('Error: --batch-size must be a positive integer');
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const batches = await batchSplit(targetDir, { batchSize });
|
|
179
|
+
console.log(JSON.stringify(batches, null, 2));
|
|
180
|
+
} catch (err) {
|
|
181
|
+
console.error(`Error: ${err.message}`);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @feature ACA17
|
|
3
|
+
// @scenario S-51
|
|
4
|
+
// @scenario S-53
|
|
5
|
+
// @scenario S-54
|
|
6
|
+
// @decision D-ACA-17
|
|
7
|
+
// Thin CLI wrapper. scripts/lib/workflow-profile.mjs is the single resolver.
|
|
8
|
+
import { resolve } from 'node:path';
|
|
9
|
+
import { buildCheckerOutput } from './lib/workflow-profile.mjs';
|
|
10
|
+
|
|
11
|
+
export async function checkWorkflowProfile({ root = process.cwd(), action = 'review', domain, profilePath, target } = {}) {
|
|
12
|
+
const projectRoot = resolve(root);
|
|
13
|
+
const checker = await buildCheckerOutput({ root: projectRoot, profilePath, intent: action, domain, target });
|
|
14
|
+
return {
|
|
15
|
+
...checker,
|
|
16
|
+
root: projectRoot,
|
|
17
|
+
action,
|
|
18
|
+
domain,
|
|
19
|
+
profile: checker.profile_path,
|
|
20
|
+
worker: checker.worker_path ? checker.worker_path.split('/').slice(-2, -1)[0] : null,
|
|
21
|
+
dry_run: true,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const isMain = import.meta.url === `file://${process.argv[1]}`;
|
|
26
|
+
if (isMain) {
|
|
27
|
+
const args = process.argv.slice(2);
|
|
28
|
+
const value = flag => {
|
|
29
|
+
const index = args.indexOf(flag);
|
|
30
|
+
return index >= 0 ? args[index + 1] : undefined;
|
|
31
|
+
};
|
|
32
|
+
if (args.includes('--help')) {
|
|
33
|
+
console.log('Usage: node check-workflow-profile.mjs --root <path> --action <generate|review|repair|audit|batch> --domain <type> [--profile <json|yaml>] [--target <path>] [--format json|text]');
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
let result;
|
|
37
|
+
try {
|
|
38
|
+
result = await checkWorkflowProfile({
|
|
39
|
+
root: value('--root') ?? process.cwd(),
|
|
40
|
+
action: value('--action') ?? 'review',
|
|
41
|
+
domain: value('--domain'),
|
|
42
|
+
profilePath: value('--profile'),
|
|
43
|
+
target: value('--target'),
|
|
44
|
+
});
|
|
45
|
+
} catch (error) {
|
|
46
|
+
result = {
|
|
47
|
+
status: 'BLOCKED', schema: null, profile_path: null, execution_mode: null,
|
|
48
|
+
worker_path: null, checklist_paths: [], validators: [], template_paths: [],
|
|
49
|
+
diagnostics: [`Checker failed closed: ${error.message}`],
|
|
50
|
+
next: 'Fix the malformed or unsafe profile and run this check again.',
|
|
51
|
+
root: resolve(value('--root') ?? process.cwd()),
|
|
52
|
+
action: value('--action') ?? 'review', domain: value('--domain'), profile: null,
|
|
53
|
+
worker: null, dry_run: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if ((value('--format') ?? 'json') === 'text') {
|
|
57
|
+
console.log(`${result.status}: ${result.action}/${result.domain ?? '(missing)'}`);
|
|
58
|
+
for (const item of result.diagnostics) console.log(`- ${item}`);
|
|
59
|
+
console.log(`Next: ${result.next}`);
|
|
60
|
+
} else {
|
|
61
|
+
console.log(JSON.stringify(result, null, 2));
|
|
62
|
+
}
|
|
63
|
+
process.exit(result.status === 'OK' ? 0 : 2);
|
|
64
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @scenario S-06 @feature ACA3
|
|
3
|
+
// @scenario S-44 @feature ACA13
|
|
4
|
+
// @decision D-ACA-15
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { resolve } from 'node:path';
|
|
7
|
+
import { inspectArtifactGraphRuntime } from './lib/artifact-graph-runtime.mjs';
|
|
8
|
+
|
|
9
|
+
// Parse --root from args (same as artifact-graph CLI convention)
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
let projectRoot = process.cwd();
|
|
12
|
+
const rootIdx = args.indexOf('--root');
|
|
13
|
+
if (rootIdx !== -1 && args[rootIdx + 1]) {
|
|
14
|
+
projectRoot = resolve(args[rootIdx + 1]);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const runtime = await inspectArtifactGraphRuntime({ projectRoot });
|
|
18
|
+
|
|
19
|
+
if (!runtime.ok) {
|
|
20
|
+
const lines = [
|
|
21
|
+
`artifact-chain-assistant: doctor pre-check failed`,
|
|
22
|
+
` reason: ${runtime.reason}`,
|
|
23
|
+
];
|
|
24
|
+
if (runtime.cliPath) lines.push(` cli: ${runtime.cliPath}`);
|
|
25
|
+
if (runtime.packagePath) lines.push(` package: ${runtime.packagePath}`);
|
|
26
|
+
if (runtime.actualVersion != null) lines.push(` actual version: ${runtime.actualVersion}`);
|
|
27
|
+
if (runtime.expectedVersion != null) lines.push(` expected version: ${runtime.expectedVersion}`);
|
|
28
|
+
if (runtime.remediation) lines.push(` fix: ${runtime.remediation}`);
|
|
29
|
+
process.stderr.write(lines.join('\n') + '\n');
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
} else {
|
|
32
|
+
// Forward all args to the real artifact-graph doctor
|
|
33
|
+
const result = spawnSync(runtime.cliPath, ['doctor', ...args], {
|
|
34
|
+
cwd: process.cwd(),
|
|
35
|
+
stdio: 'inherit',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (result.error) {
|
|
39
|
+
process.stderr.write(`artifact-chain-assistant: failed to run artifact-graph doctor: ${result.error.message}\n`);
|
|
40
|
+
process.exitCode = 127;
|
|
41
|
+
} else {
|
|
42
|
+
process.exitCode = result.status ?? 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @scenario S-44 @feature ACA13 @feature ACA3
|
|
3
|
+
// @decision D-ACA-15
|
|
4
|
+
import { access, readFile, realpath } from 'node:fs/promises';
|
|
5
|
+
import { delimiter, join, dirname, resolve } from 'node:path';
|
|
6
|
+
import { loadCompatibilityPolicy } from './compatibility-policy.mjs';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Locate the artifact-graph CLI in a target project, resolve its package version,
|
|
10
|
+
* and compare against the plugin's compatibility policy.
|
|
11
|
+
*
|
|
12
|
+
* Resolution order:
|
|
13
|
+
* 1. <projectRoot>/node_modules/.bin/artifact-graph
|
|
14
|
+
* 2. PATH lookup for artifact-graph
|
|
15
|
+
* 3. ARTIFACT_GRAPH_LEGACY_CLI env var (explicit fallback)
|
|
16
|
+
*
|
|
17
|
+
* For the resolved CLI, look up its owning package.json (name === "artifact-graph")
|
|
18
|
+
* and compare the version field against policy.artifactGraph.verifiedVersion.
|
|
19
|
+
*
|
|
20
|
+
* @param {{ projectRoot: string, env?: Record<string,string> }} opts
|
|
21
|
+
* @returns {Promise<{ok: boolean, cliPath?: string, packagePath?: string, actualVersion?: string, expectedVersion?: string, reason?: string, remediation?: string}>}
|
|
22
|
+
*/
|
|
23
|
+
export async function inspectArtifactGraphRuntime({ projectRoot, env }) {
|
|
24
|
+
const pluginRoot = resolve(import.meta.dirname, '..', '..');
|
|
25
|
+
let policy;
|
|
26
|
+
try {
|
|
27
|
+
policy = await loadCompatibilityPolicy(pluginRoot);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
reason: 'policy_load_failed',
|
|
32
|
+
remediation: `Failed to load compatibility policy: ${error.message}`,
|
|
33
|
+
expectedVersion: null,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const expectedVersion = policy.artifactGraph.verifiedVersion;
|
|
38
|
+
const installSpec = policy.artifactGraph.installSpec;
|
|
39
|
+
|
|
40
|
+
// 1. Try project-local CLI first
|
|
41
|
+
const localBin = join(projectRoot, 'node_modules', '.bin', 'artifact-graph');
|
|
42
|
+
let cliPath = await resolveIfExecutable(localBin);
|
|
43
|
+
|
|
44
|
+
// 2. Try PATH
|
|
45
|
+
if (!cliPath) {
|
|
46
|
+
cliPath = await findOnPath(env ?? process.env);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 3. Try explicit legacy CLI override
|
|
50
|
+
if (!cliPath) {
|
|
51
|
+
const legacy = (env ?? process.env).ARTIFACT_GRAPH_LEGACY_CLI;
|
|
52
|
+
if (legacy) {
|
|
53
|
+
cliPath = await resolveIfExecutable(legacy);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!cliPath) {
|
|
58
|
+
return {
|
|
59
|
+
ok: false,
|
|
60
|
+
reason: 'cli_not_found',
|
|
61
|
+
expectedVersion,
|
|
62
|
+
remediation: `artifact-graph CLI not found. Run: pnpm add -D ${installSpec}`,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 4. Resolve the owning package.json
|
|
67
|
+
const { packagePath, version } = await resolvePackageVersion(cliPath);
|
|
68
|
+
|
|
69
|
+
if (!version) {
|
|
70
|
+
return {
|
|
71
|
+
ok: false,
|
|
72
|
+
cliPath,
|
|
73
|
+
packagePath,
|
|
74
|
+
reason: 'version_unresolved',
|
|
75
|
+
expectedVersion,
|
|
76
|
+
remediation: `Could not determine artifact-graph version from ${packagePath || cliPath}. Run: pnpm add -D ${installSpec}`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (version !== expectedVersion) {
|
|
81
|
+
return {
|
|
82
|
+
ok: false,
|
|
83
|
+
cliPath,
|
|
84
|
+
packagePath,
|
|
85
|
+
actualVersion: version,
|
|
86
|
+
expectedVersion,
|
|
87
|
+
reason: 'version_mismatch',
|
|
88
|
+
remediation: `artifact-graph version is ${version}, expected ${expectedVersion}. Run: pnpm add -D ${installSpec}`,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
ok: true,
|
|
94
|
+
cliPath,
|
|
95
|
+
packagePath,
|
|
96
|
+
actualVersion: version,
|
|
97
|
+
expectedVersion,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Resolve a path to its realpath if it exists and is executable (X_OK).
|
|
103
|
+
*/
|
|
104
|
+
async function resolveIfExecutable(path) {
|
|
105
|
+
try {
|
|
106
|
+
const real = await realpath(path);
|
|
107
|
+
await access(real, 1); // X_OK = 1
|
|
108
|
+
return real;
|
|
109
|
+
} catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Search PATH for artifact-graph binary.
|
|
116
|
+
* Does NOT check ARTIFACT_GRAPH_LEGACY_CLI — that's the caller's fallback.
|
|
117
|
+
*/
|
|
118
|
+
export async function findOnPath(env) {
|
|
119
|
+
const pathEnv = env.PATH || '';
|
|
120
|
+
const pathDirs = pathEnv.split(delimiter);
|
|
121
|
+
|
|
122
|
+
for (const dir of pathDirs) {
|
|
123
|
+
if (!dir) continue;
|
|
124
|
+
const candidate = join(dir, 'artifact-graph');
|
|
125
|
+
const resolved = await resolveIfExecutable(candidate);
|
|
126
|
+
if (resolved) return resolved;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Given a CLI path, find the owning artifact-graph package.json and its version.
|
|
134
|
+
*
|
|
135
|
+
* Strategy:
|
|
136
|
+
* 1. Walk up from the CLI directory looking for package.json with name === "artifact-graph".
|
|
137
|
+
* 2. If CLI is under .bin/, also try walking up from the sibling artifact-graph/ package directory.
|
|
138
|
+
*
|
|
139
|
+
* Returns { packagePath, version } or { packagePath: null, version: null }.
|
|
140
|
+
*/
|
|
141
|
+
export async function resolvePackageVersion(cliPath) {
|
|
142
|
+
// Strategy 1: walk up from CLI location
|
|
143
|
+
const result = await walkUpForPackage(dirname(cliPath));
|
|
144
|
+
if (result.packagePath) return result;
|
|
145
|
+
|
|
146
|
+
// Strategy 2: if CLI is under a .bin/ directory, check sibling package directories
|
|
147
|
+
const dir = dirname(cliPath);
|
|
148
|
+
const parentDir = dirname(dir);
|
|
149
|
+
if (dir.endsWith('.bin') || dir.endsWith('.bin/')) {
|
|
150
|
+
// Check parentDir/artifact-graph/package.json directly
|
|
151
|
+
const siblingPkg = join(parentDir, 'artifact-graph', 'package.json');
|
|
152
|
+
try {
|
|
153
|
+
const raw = await readFile(siblingPkg, 'utf8');
|
|
154
|
+
const pkg = JSON.parse(raw);
|
|
155
|
+
if (pkg.name === 'artifact-graph') {
|
|
156
|
+
return { packagePath: siblingPkg, version: pkg.version || null };
|
|
157
|
+
}
|
|
158
|
+
} catch {
|
|
159
|
+
// No sibling package found
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return { packagePath: null, version: null };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function walkUpForPackage(startDir) {
|
|
167
|
+
let dir = startDir;
|
|
168
|
+
const seen = new Set();
|
|
169
|
+
|
|
170
|
+
while (dir && !seen.has(dir)) {
|
|
171
|
+
seen.add(dir);
|
|
172
|
+
const pkgPath = join(dir, 'package.json');
|
|
173
|
+
try {
|
|
174
|
+
const raw = await readFile(pkgPath, 'utf8');
|
|
175
|
+
const pkg = JSON.parse(raw);
|
|
176
|
+
if (pkg.name === 'artifact-graph') {
|
|
177
|
+
return { packagePath: pkgPath, version: pkg.version || null };
|
|
178
|
+
}
|
|
179
|
+
} catch {
|
|
180
|
+
// No package.json at this level, or not valid JSON
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const parent = dirname(dir);
|
|
184
|
+
if (parent === dir) break;
|
|
185
|
+
dir = parent;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return { packagePath: null, version: null };
|
|
189
|
+
}
|